1

我正在将 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>());

我是否需要使用哪个为每个数据上下文提供唯一的名称NamedDependsOnconnectionString 参数?

用户选择数据库后,我目前在运行时注册数据上下文的操作

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());
4

1 回答 1

1

注入一个包装类来保存连接字符串并让数据上下文对象使用它呢?这些方面的东西:

public class ConnectionStringProvider : IConnectionStringProvider
{
    private string _value;

    public event EventHandler ConnectionStringChanged;

    public string ConnectionString
    {
        get { return _value; }
        set
        {
            _value = value;

            var del = ValueChanged;
            if (del != null)
                del(this, EventArgs.Empty);
        }
    }
}

将此注册为单身人士的生活方式。这样,您的应用程序可以设置或更新单个对象上的连接字符串,并且依赖它的每个人都会收到更改通知。

于 2012-05-29T14:42:27.180 回答