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
を見て、パラメータをサポートして独自の実装を構築する方法を見てみることをお勧めします。
私は混乱しています。 'MyExportFactory'について話しましたが、' SrviceProviderFactory'というクラスを表示します。 'CreateServiceProvider'メソッドを定義しますが、' CreateMyExport'を呼び出す別のメソッドも定義します。質問を書いている間に名前を変更しましたか? –