2010-12-11 3 views
6

MEFを使用するデスクトップアプリケーションは、多くの 'ServiceProviders'をインポートします。各パート(ServiceProvider)は、別々のDLL内のクラスです。 すべてのDLLは、デスクトップアプリケーションで使用される「プラグイン」フォルダにあります。カスタム 'ExportFactory'

私は部品の新しいインスタンスを必要とするので、ExportFactoryが最良の選択だった。問題は私の部品はコンストラクタを持っている。私は、コンストラクタにいくつかのパラメータを渡す必要があります。私は私の部品側から何かをインポートしたくない

// Each part has its own dependency 
Dependency dependency = LoadDependency(myPart.Metedata["Name"]); 
// Injecting dependency into part's constructor 
myPart.CreateExport(dependency); 

ExportFactory(MEF2、Preview2)によってサポートされていない部分

の私はこのようなものが必要。 0

サンプルプロジェクト(パラメータなしのコンストラクタを使用)はhereです。

+0

私は混乱しています。 'MyExportFactory'について話しましたが、' SrviceProviderFactory'というクラスを表示します。 'CreateServiceProvider'メソッドを定義しますが、' CreateMyExport'を呼び出す別のメソッドも定義します。質問を書いている間に名前を変更しましたか? –

答えて

5

MEFはタイプExportFactory<IFoo>のインポートを見ると、これを特別な方法で処理します。文字通りExportFactory<IFoo>のエクスポートを探す代わりに、IFooのエクスポートを探し、そのタイプのファクトリを魔法のように生成します。

あなたの間違いは、SrviceProviderFactoryと呼ばれるExportFactoryの代わりに、この魔法が自動的に機能すると期待していることです。本当じゃない。 SrviceProviderFactory<IFoo,IFooMetadata>をどこかにインポートすると、MEFは文字通りそのタイプのエクスポートを探します。

簡単な解決方法は、このエクスポートを行うことです。各IServiceProvider実装のファクトリを手動でエクスポートします。たとえば、あなたがFooServiceProviderを持っている場合、:

public class FooServiceProvider : IServiceProvider 
{ 
    public FooServiceProvider(Dependency dependency) 
    { 
     ... 
    } 
} 

次にあなたもFooServiceProviderFactoryを持っている必要があります。

[Export(typeof(IServiceProviderFactory))] 
[ExportMetaData("foo", "bar")] 
public class FooServiceProviderFactory : IServiceProviderFactory 
{ 
    public IServiceProvider CreateServiceProvider(Dependency d) 
    { 
     return new FooServiceProvider(d); 
    } 
} 

そして、あなたの輸入は、メタデータに基づいて、右の工場を選択することができます。

public class FactoryUser 
{ 
    [ImportMany] 
    public Lazy<IServiceProviderFactory,IDictionary<string,object>>[] Factories 
    { 
     get; 
     set; 
    } 

    public void DoSomething() 
    { 
     var factory = Factories.First(x => x.Metadata["foo"] == "bar").Value; 
     var serviceProvider = factory.CreateServiceProvider(someDependency); 
     ... 
    } 
} 

ここで厄介なことは、各サービスプロバイダの実装では、ファクトリ実装を作成してエクスポートする必要があることです。共通のファクトリベースクラス(SrviceProviderFactoryなど)を作成することで作業を保存できますが、MEFエクスポートで汎用タイプのパラメータを使用できないため、特定のクラスを引き続き取得する必要があります。 更新:.NET 4.5ではオープンジェネリック型のエクスポートがサポートされていると思います。

だから、I already suggested you export Func insteadだが、明らかにその答えが気に入らなかった。

また、ExportFactoryの魔法を複製することもできます。これは可能ですが、MEFの非常に高度な使用例です。そのためには、MEFのソースExportFactoryProviderを見て、パラメータをサポートして独自の実装を構築する方法を見てみることをお勧めします。

関連する問題