我正在将 Windsor IoC 容器添加到使用 MVP UI 设计模式的现有 WinForms 应用程序中。我正在尝试确定一种重新注册数据上下文的好方法,该数据上下文取决于运行时提供的连接字符串。问题是在用户选择数据库之前我无法创建数据上下文,即应用程序加载后的“连接字符串”。通常只使用一个数据上下文,但有时用户需要切换到不同的数据库,即创建不同的数据上下文。这也会导致额外的运行时依赖。
public interface IProductsView
{
event EventHandler<ProductSelectedEventArgs> ProductSelectedEvent;
event EventHandler<StringEventArgs> ProductStatusEvent;
void ClearProductList();
void DisplayProductList(IList<Product> products);
Control Control { get; }
IProductsPresenter Presenter { get; set; }
}
public class ProductsPresenter : IProductsPresenter
{
public IProductsView View { get; set; }
private IProductRepository Repository { get; set; }
public ProductsPresenter(IProductsView view, IProductRepository repository)
{
View = view;
View.Presenter = this;
Repository = repository;
}
public void ProductSelected(IList<Product> products)
{
throw new NotImplementedException();
}
public void ShowProductList(string name)
{
IList<Product> productList;
if (string.IsNullOrEmpty(name))
productList = Repository.GetProducts();
else
productList = Repository.GetProductsByName(name);
View.DisplayProductList(productList);
}
}
public class ProductDao : IDisposable, IProductRepository
{
private MeasurementDataContext dataContext;
public ProductDao(MeasurementDataContext context)
{
dataContext = context;
}
public List<Product> GetProducts()
{
return dataContext.Products.Select(p => Mapper.Map(p)).ToList().OrderBy(x => x.Name).ToList();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
if (dataContext != null)
{
dataContext.Dispose();
dataContext = null;
}
}
~ProductDao()
{
this.Dispose(false);
}
}
所以这意味着Presenter
在 my中的 in 在创建View
之前是 null IProductRepository
,而这又取决于创建一个MeasurementDataContext
. 我以这样的方式注册了这些组件IWindsorInstaller
:
container.Register(Component.For<IProductsView>()
.ImplementedBy<ViewProductsControl>());
container.Register(Component.For<IProductsPresenter>()
.ImplementedBy<ProductsPresenter>());
我是否需要使用哪个为每个数据上下文提供唯一的名称Named
和DependsOn
connectionString 参数?
用户选择数据库后,我目前在运行时注册数据上下文的操作
kernel.Register(Component.For<MeasurementDataContext>()
.UsingFactoryMethod(() => new MeasurementDataContext(conn)));
然后“解决”我的视图并设置他们的演示者。我知道这不是好的设计,但它是解决我的依赖的蛮力方式。
谢谢
更新:
我将在安装程序中注册数据上下文的方式更改为以下内容:
container.Register(Component.For<DataContext>().ImplementedBy<MeasurementDataContext>().Named("Localhost").DependsOn(new { connectionString = conn }));
然后将我模型的构造函数修改为:
public ProductDao(DataContext context)
{
dataContext = context as MeasurementDataContext;
}
所有组件都将使用正确的键解析:
kernel.Resolve<DataContext>(cbo.SelectedItem.ToString());