MVP UI デザイン パターンを使用する既存の WinForms アプリケーションに Windsor IoC コンテナーを追加する作業を行っています。実行時に提供される接続文字列に依存するデータコンテキストを登録するための適切なアプローチを決定しようとしています。問題は、アプリケーションがロードされた後、ユーザーがデータベース、つまり「接続文字列」を選択するまで、データコンテキストを作成できないことです。通常は 1 つのデータコンテキストのみが使用されますが、ユーザーが別のデータベースに切り替える必要がある場合があります。つまり、別のデータコンテキストを作成する場合です。これにより、追加のランタイム依存関係も発生します。
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 内のView
が nullであることを意味します。これは、 のIProductRepository
作成に依存しMeasurementDataContext
ます。私はこれらのコンポーネントを次のIWindsorInstaller
ように登録しています:
container.Register(Component.For<IProductsView>()
.ImplementedBy<ViewProductsControl>());
container.Register(Component.For<IProductsPresenter>()
.ImplementedBy<ProductsPresenter>());
各データコンテキストに一意の名前と connectionString 引数を指定する必要がありNamed
ますか?DependsOn
ユーザーがデータベースを選択した後、実行時にデータコンテキストを登録するために現在行っていること
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());