問題は、ビューとプレゼンターが相互に依存しているため、それらの間に依存サイクルがあることです。この依存関係のサイクルを断ち切る際の一般的なルールは、プロパティインジェクションにフォールバックすることです。これは、あなたの場合にも機能します。
MVPを使用する場合は、ビューをプレゼンターのプロパティに挿入して、作成したプレゼンターにビューを割り当てることをお勧めします。
mPresenter = container.Resolve<Presenter>();
mPresenter.View = this;
可能であれば、コンテナをアプリケーションから非表示にします。MVPを使用しているため、直接解決する必要があるのはプレゼンターだけです。したがって、フォームをコンテナと通信させるのではなく、静的なと通信させますPresenterFactory
。この工場は、カバーの下でコンテナを使用します。
mPresenter = PresenterFactory.Create<MyPresenter>();
mPresenter.View = this;
あなたPresenterFactory
はこのように見えるかもしれません:
public static class PresenterFactory
{
private static IContainer container;
public static TPresenter Create<TPresenter>()
where TPresenter : IPresenter
{
return (TPresenter)
container.Resolve(typeof(TPresenter));
}
public static void SetContainer(IContainer container)
{
PresenterFactory.container = container;
}
}
また、コンポジションルートは次のようになります。
static void Main()
{
Bootstrap();
}
private static void Bootstrap()
{
var builder = new ContainerBuilder();
// TODO: register presenters
var container = builder.Build();
PresenterFactory.SetContainer(container);
}
アップデート
おそらく、次のようなことをするのがさらに良いでしょう:
interface IPresenter<TView>
{
TView View { get; set; }
}
public static class PresenterFactory
{
private static IContainer container;
public static IPresenter<TView> CreateForView<TView>(TView view)
{
var presenter = container.Resolve<IPresenter<TView>>();
presenter.View = view;
return presenter;
}
}
// View
mPresenter = PresenterFactory.CreateForView(this);
これにより、プレゼンターの実際の実装がビューから隠され、ビューの登録がプレゼンターに一元化されます。