Winforms Castle Windsor的运行时数据上下文

Winforms Castle Windsor的运行时数据上下文,winforms,dependency-injection,inversion-of-control,castle-windsor,ioc-container,Winforms,Dependency Injection,Inversion Of Control,Castle Windsor,Ioc Container,我正在致力于向使用MVP UI设计模式的现有WinForms应用程序添加Windsor IoC容器。我试图确定一种重新注册datacontext的好方法,该方法依赖于运行时提供的连接字符串。问题是,在用户选择数据库之前,即在应用程序加载后选择“连接字符串”,我无法创建datacontext。通常只使用一个datacontext,但有时用户需要切换到不同的数据库,即创建不同的datacontext。这也会导致额外的运行时依赖关系 public interface IProductsView {

我正在致力于向使用MVP UI设计模式的现有WinForms应用程序添加Windsor IoC容器。我试图确定一种重新注册datacontext的好方法,该方法依赖于运行时提供的连接字符串。问题是,在用户选择数据库之前,即在应用程序加载后选择“连接字符串”,我无法创建datacontext。通常只使用一个datacontext,但有时用户需要切换到不同的数据库,即创建不同的datacontext。这也会导致额外的运行时依赖关系

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);
    }
}
是否需要使用
Named
DependsOn
为每个datacontext提供唯一的名称和connectionString参数

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

kernel.Register(Component.For<MeasurementDataContext>()
               .UsingFactoryMethod(() => new MeasurementDataContext(conn)));
所有组件将使用正确的键解析:

kernel.Resolve<DataContext>(cbo.SelectedItem.ToString());
kernel.Resolve(cbo.SelectedItem.ToString());

如何注入包装器类来保存连接字符串,并让datacontext对象使用它?大致如下:

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);
        }
    }
}

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

如何注入包装器类来保存连接字符串并让datacontext对象使用它?大致如下:

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);
        }
    }
}

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

与您的问题无关,但没有理由实施Dispose模式的full-blow finalizer版本,因为您只处理托管资源。如果您的终结器执行,它将不会做任何事情(Dispose()方法中的diposing=false不会产生任何结果);这将是一个不必要的性能损失。与您的问题无关,但没有理由实施Dispose模式的全面终结器版本,因为您只处理托管资源。如果您的终结器执行,它将不会做任何事情(Dispose()方法中的diposing=false不会产生任何结果);这将是一个不必要的性能惩罚。谢谢你的建议!我结束了在安装程序中如何注册datacontext的更改,如上面编辑的文章所示。我不确定如何注册datacontext,因此它取决于包装器类。你有例子吗?谢谢你的建议!我结束了在安装程序中如何注册datacontext的更改,如上面编辑的文章所示。我不确定如何注册datacontext,因此它取决于包装器类。你有一个例子吗?
kernel.Resolve<DataContext>(cbo.SelectedItem.ToString());
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);
        }
    }
}