6

winforms アプリで IoC の概念を理解しようとしています。コンストラクターがそのビューとサービスをコンストラクター引数として受け取るプレゼンターがあるとします。したがって、フォームコードには、これに相当するものがあります。

mnPresenter = new Presenter(this, new AppService());

ここで、AppService は IAppService の実装であるとします。私の[autofac]IoCコンテナに登録されています。このプレゼンターの構造から「新しい」ものを引き出すための推奨される方法は何ですか? 上記のように、IoC フレームワークを使用してこれらの「新しい」呼び出しを失うことの要点ではありませんか?

私は次のようなことができます

mPresenter = new Presenter(this, MyContainer.Resolve<IAppService>())

しかし、それは IoC の目的に反しているようです。私はおそらくここで基本的な何かを見逃しています。

明らかな何かが欠けている場合は、事前にお詫び申し上げます。

4

2 に答える 2

9

問題は、ビューとプレゼンターが相互に依存しているため、それらの間に依存サイクルがあることです。この依存関係のサイクルを断ち切る際の一般的なルールは、プロパティインジェクションにフォールバックすることです。これは、あなたの場合にも機能します。

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

これにより、プレゼンターの実際の実装がビューから隠され、ビューの登録がプレゼンターに一元化されます。

于 2012-07-31T10:37:49.750 に答える
1

プレゼンターにプロパティが必要です

public IAppService service;

コンテナによって注入されるため、パラメータとして渡す必要はありません。あなたが書いたのはサービスロケーターであり、実際にはIoCのアンチパターンです。

ビューが厳密に型指定され、コンテナーにも登録されている場合は、Autofac の .SingleInstance ライフサイクルとプロパティを使用できます。

public IMyView view;

プレゼンテーションでは、コンテナーはビュー インスタンスをプレゼンターに挿入します。

あなたは基本的に別の質問でコードを見てください: ビューでプレゼンターを登録する

于 2012-11-08T13:36:20.333 に答える