6

私の Prism アプリでは、MEF コンテナーは Container プロパティを介して Bootstrapper クラス内から利用できます。

ただし、クラス モジュール (IModule) 内からではありません。IServiceLocator を介してのみコンテナーをインポートできます。

なんで?具体的なテクノロジーに対して共通のインターフェイスを使用することは理にかなっていると思いましたが、Prism 4.1 ガイドラインでは IServiceLocator を使用しないように求められています ( IServiceLocatorの使用に関する考慮事項)。

4

2 に答える 2

6

PrismやMEFではなく、Dependency Injectionの原則やベストプラクティス全般に対応していると思います。(ええ、私は MEF が DI コンテナーではないことを結びますが、ここではほとんど DI コンテナーとして使用されるため、ここで同じプラクティスを使用すると思います)。

DI のベスト プラクティス (この本は非常にクールです。強くお勧めします) では、DI の「ワークフロー」に次のような手順を含めることをお勧めします。

  • 必要なすべてのタイプを登録します (Prism で - Bootstrapper.ConfigureCatalog() メソッドによる)
  • ルート オブジェクトを解決します (すべてのネストされたオブジェクトを含む。Prism では - Bootstrapper.CreateShell() メソッドによる)
  • ルートオブジェクトを使用する
  • ルートオブジェクトを解放する

理想的には、DI コンテナーはもう使用しないでください。あなたのコードは DI コンテナの存在を認識すべきではありません (この点から見ると、Unity は実際には DI コンテナです。なぜなら、DI コンテナの使用を認識しないコードを書くことができるからです)。あなたのコードがそれを知っている場合 - それは DI コンテナに依存しており、悪いことです。

PS。とにかくモジュールで MEF コンテナーを使用したい場合 (たとえば、DI パラダイムにあまり慣れていないか、非常に特殊なタスクがあるため)、次のようなことを試すことができます。

[ModuleExport(typeof(YourModule))]
public class YourModule : IModule
{
    public static CompositionContainer CompositionContainer;

    [ImportingConstructor]
    public void YourModule(CompositionContainer container)
    {
        this.CompositionContainer = container;
    }
}

MEF コンテナー自体を Boostrapper に登録することを忘れないでください。

public class YourBootstrapper: MefBootstrapper
{
    protected override CompositionContainer CreateContainer()
    {
        var container = base.CreateContainer();
        container.ComposeExportedValue(container);
        return container;
    }
}
于 2012-05-31T04:57:58.877 に答える
0

私は古いバージョンの Prism を使用しており、それを UnityContainer と共に使用していますが、同じ原則が適用されることに注意してください。

Module クラスを定義して、コンストラクターでコンテナーを受け取ります。

Unity を使用した例を次に示します。

public class Module : IModule
{
    public static IUnityContainer Container;

    public Module(IUnityContainer container)
    {
        Container = container;
    }
}

コンテナーを取るコンストラクターを定義すると、ApplicationBootstrapper.Run() メソッドによって呼び出されます。

デフォルトのパラメーターなしのコンストラクターと、コンテナーを受け取るオーバーロード コンストラクターでテストし、2 番目のコンストラクターが呼び出されました。

また、デフォルトのコンストラクターのみを持っていることを確認したところ、呼び出されました。コンストラクターを変更して、コンテナーを取るパラメーターを追加することをお勧めします。

モジュール クラスにコンテナーがあると、Initialize メソッドに型を登録できます。

ServiceLocator に関しては、これは少し異なるパターンであり、何らかの理由でコンテナーによって作成された依存関係を取得できない場合に使用することをお勧めします。

于 2012-05-30T20:05:56.220 に答える