0

次のInitialize()メソッドを持つCustomersModule.csがあります。

public void Initialize()
{
    container.RegisterType<ICustomersRepository, CustomersRepository>(new ContainerControlledLifetimeManager());
    CustomersPresenter customersPresenter = this.container.Resolve<CustomersPresenter>();

}

コンテナから解決するクラスは次のようになります。

class CustomersPresenter
{
    private CustomersView view;
    private ICustomersRepository customersRespository;

    public CustomersPresenter(CustomersView view, 
        ICustomersRepository customersRepository, 
        TestWhatever testWhatever)
    {
        this.view = view;
        this.customersRespository = customersRepository;
    }
}

TestWhateverクラスは、私が作成した単なるダミークラスです。

public class TestWhatever
{
    public string Title { get; set; }

    public TestWhatever()
    {
        Title = "this is the title";
    }

}

それでも、私が登録したことがなくても、コンテナは問題なく解決 されます。また、コンテナはどういうわけかTestWhateverを見つけてインスタンス化し、に注入します。CustomersPresenterCustomersPresenter

コンテナが非常に自動であると明示的に述べているPrismのドキュメントのどこにも見つからなかったので、これに気付いて非常に驚きました。

ですから、これは素晴らしいことですが、私が知らないコンテナは他に何をしているのでしょうか。つまり、私が知らない他に何ができるのでしょうか。たとえば、他のモジュールからクラスを注入できますか?モジュールがロードされた場合、コンテナはそれらを注入し、そうでない場合はnullを注入しますか?

4

2 に答える 2

3

魔法のようなことは何も起きていません。具体的な型を指定しているので、当然解決可能です。オブジェクトがあれば、そのTypeオブジェクトに対してコンストラクターを呼び出すことができるからです。

class Fred { };

Fred f1 = new Fred();

Type t = typeof(Fred);

Fred f2 = (Fred)t.GetConstructor(Type.EmptyTypes).Invoke(null);

上記の最後の行は実際に何が起こるかを表していtypeofますResolve

型を new で構築できない場合 (未知の別のコードベースにあるため)、それを型パラメーターとして に渡すことはできませんResolve

2 番目のケースでは、コンストラクター インジェクションですが、まだ既知の具体的な構築可能な型です。リフレクションを介して、Unity フレームワークはパラメーターのすべてのタイプの配列をコンストラクターに取得できます。型TestWhateverは構築可能であるため、何を構築するかについてあいまいさや困難はありません。

個別のモジュール (アセンブリ) に関する懸念については、TestWhatever別のアセンブリに移動しても、記述したコード行は変更されません。これをビルドするには、他のアセンブリへの参照を追加する必要があることを意味します。And thenTestWhateverは依然として明確に参照される構築可能な型であるため、Unity で構築できます。

つまり、コードで型を参照できれば、Typeオブジェクトを取得できるため、実行時に直接構築可能になります。

コメントへの返信:

class を削除するTestWhateverと、コードでその型を参照するため、コンパイル時エラーが発生します。したがって、それによってランタイムを取得することはできません。

の特定のインスタンスを登録できるため、この配置でもデカップリングは引き続き有効ですTestWhatever。そのため、 を呼び出すたびにResolve<TestWhatever>()、新しいインスタンスを作成するのではなく、同じインスタンスが取得されます。

于 2009-07-20T14:00:05.720 に答える
2

これが機能する理由は、Unity がそのように設計されているためです。具象型で解決すると、Unity はコンテナーから解決できるかどうかを確認します。できない場合は、依存関係を解決する型をインスタンス化します。それは本当にとても簡単です。

于 2009-09-12T20:57:40.507 に答える