2012-03-02 16 views
3

インポートコンストラクタが単一の依存関係を要求し、この依存関係の実装が複数ある場合、最も優先度の高い(メタデータ)実装(エクスポート)が行われるように、MEFコンポジションをオーバーライドできますか?MEFコンポジションのオーバーライド

[Export(typeof(IService))] 
[ExportMetadata("Priority", 1)] 
public class Service1 : IService 
{ 
} 

[Export(typeof(IService))] 
[ExportMetadata("Priority", 2)] 
public class Service2 : IService 
{ 
} 

public interface IService 
{ 
} 

public class ServiceWithDependencies 
{ 
    [ImportingConstructor] 
    public ServiceWithDependencies(IService service) 
    { 

    } 
} 

IServiceの複数の実装があるため、ServiceWithDependenciesは通常満たされません。しかし、MEF(override/intercept something)を変更して、優先度メタデータを使用し、ServiceWithDependenciesコンストラクタに最も高い優先順位を持つ実装を注入したいと思います。

編集1

私はMEFは、私は物事を行う方法を指示する必要はありません。私はそれができるだけ目に見えないようにしたい。さらに、これはフレームワークのためのものであり、私は人々が依存関係をどのように必要とするかを制御していません。基本的なコンストラクタインジェクションをサポートする必要があります。私は[ImportMany]について知っていますが、この質問はコンストラクタインジェクションについてのものです。

答えて

2

、あなたはまた、別のカタログに入れ、その後prioritize the catalogsことができます。

私たちのアプリケーションでは、pluginsフォルダー内の部品、次にアプリケーション内の部品、そして最後に他のすべてのライブラリーを最優先に使用しています。

編集:完全なサンプルです。

まず、タイプ:に関しては

var priorityCatalog = new TypeCatalog(typeof(Service1)); 
var priorityProvider = new CatalogExportProvider(priorityCatalog); 

var mainCatalog = new TypeCatalog(
    typeof(ServiceWithDependencies), 
    typeof(ServiceWithMultipleDependencies), 
    typeof(Service2)); 
var mainProvider = new CatalogExportProvider(mainCatalog); 

// priorityProvider gets priority because it is first 
var container = new CompositionContainer(
    priorityProvider, mainProvider); 
priorityProvider.SourceProvider = container; 
mainProvider.SourceProvider = container; 

// will get constructed with Service1 
var foo = container.GetExportedValue<ServiceWithDependency>(); 

// will get constructed with both, proving that both are available 
var bar = container.GetExportedValue<ServiceWithMultipleDependencies>(); 
+0

私は遅いですが、これがどのようにコンストラクタインジェクションに役立つか分かりません。 – W3Max

+0

コンストラクタインジェクションとコンフリクトがないので、コンストラクタインジェクションも使用します。 –

+0

問題があるとは言わなかったが、私はそれがどのように機能するのか分からないと言った。もう一度申し訳ありませんが、私はMEF界の初心者です。上の例の文脈で説明できますか? – W3Max

1

[ImportMany]には簡単な方法があり、最高のメタデータを持つものを選ぶことができます。 < - 私たちのプロジェクトで何をしているのですか?

あなたができることの詳細 - hereが見つかりました。

public class ServiceWithDependencies 
{ 
    [ImportingConstructor] 
    public ServiceWithDependencies([ImportManyAttribute]IEnumerable<Lazy<IService, IServiceMetadata>> services) 
    { 
     this._TheServiceIWant = services.Max(x=>x.Metadata.Prio).First().Instance; 
    } 
} 

PS:LINQは右ではないであろうように、コードは、手書きである - 多分

EDIT:

の代わりに、直接あなたにもインポートすることができ、工場のウィッヒは、いくつかのメソッドを持って、あなたのクラスのサービスを処理以下のように:代わりにあなたの部分に優先メタデータを置くの

MyPluginFac.GiveServiceWithHighestPrio(); 
MyPluginFac.GiveServiceWithPrio(1); 
... 

public class ServiceWithDependencies 
{ 
    [ImportingConstructor] 
    public ServiceWithDependencies(IServiceFac serviceFac) 
    { 
     this._TheServiceIWant = serviceFac.GiveServiceWithHighestPrio(); 
    } 
} 
+0

が、これはあまりにも多くの儀式である:ここ

[Export(typeof(IService))] public class Service1 : IService { } [Export(typeof(IService))] public class Service2 : IService { } public interface IService { } [Export] public class ServiceWithDependency { [ImportingConstructor] public ServiceWithDependency(IService service) { } } [Export] public class ServiceWithMultipleDependencies { [ImportingConstructor] public ServiceWithMultipleDependencies( [ImportMany] IEnumerable<IService> services) { } } 

そして、あなたは、コンテナを設定することができる方法です。私は、MEFが私のやり方を指示するのを望まない。私はそれができるだけ目に見えないようにしたい。さらに、これはフレームワークのためのものであり、私は人々が依存関係をどのように必要とするかを制御していません。基本的なコンストラクタインジェクションをサポートする必要があります。私は[ImportMany]について知っていますが、この質問はコンストラクタインジェクションについてのものです。 – W3Max

+0

ファクトリーソリューションの良い点は、1つのコンテナがあり、その中から必要なものを得ることができることです。 – blindmeis

+0

あなたは正しいですが、IServiceの代わりにIServiceFacをインポートする必要があります – blindmeis