2012-04-15 14 views
1

次のような状況があります。アセンブリAにIは、以下を有する:組立体BおよびCにおいてMEFで引数を構成してクラスのインスタンスを作成

public class Service : IService 
{ 
    private readonly IDependency dependency; 

    public Service(IDependency dependency) 
    { 
     this.dependency = dependency; 
    } 
} 

IはIDependencyの異なる実装を有する:

私はMEFエクスポート IDependenciesのそれぞれについて Serviceのインスタンスを作成するように指示することができる方法
[Export(typeof(IDependency)] 
public class Dependency1 : IDependency { } 

[Export(typeof(IDependency)] 
public class Dependency2 : IDependency { } 

答えて

2

MEFではこれをそのまま使用することはできません。

  1. は、おそらくあなたは、サービスのすべてのインスタンスをインポートする[ImportMany(typeof(IService))]どこかを行うことを計画:2つのオプションがあります。

    [Export] 
    public class ServiceProvider 
    { 
        [ImportMany] 
        public IEnumerable<IDependency> Dependencies { get; set; } 
    
        public IEnumerable<IService> GetServices() 
        { 
         return Dependencies.Select(x => new Service(x)); 
        } 
    } 
    
  2. あなたがあなた自身の輸出プロバイダの実装でMEFを増やすことができます。その代わり、あなたはこのように実装ServiceProviderオブジェクトをインポートすることができます。私は[ExportMany]アトリビュートを追加するというアイデアを思いつきましたが、このアトリビュートはカスタムエクスポートプロバイダによって認識されます。それはうまくいくようですが、概念の証明に過ぎません。 https://bitbucket.org/wcoenen/mefexportmany/を参照してください。

1

ウィムが言ったように、これはネイティブでサポートされていません。あなたはこのような何かを行うことができるようにしたい場合:

[ImportMany] 
public IEnumerable<Service> _services { get; set; } 

...工場(ヴィムによる詳細などServiceProvider)を使用せずに、エクスポート・プロバイダは、例えば、動作します:

public class ServiceExportProvider : ExportProvider 
{ 
    private const string ContractName = AttributedModelServices.GetContractName(typeof(Service)); 

    public ExportProvider SourceProvider { get; set; } 

    protected override IEnumerable<Export> GetExportsCore(ImportDefinition def, AtomicComposition ac) 
    { 
    if (SourceProvider == null) 
     throw new InvalidOperationException("SourceProvider property must be set."); 

    if (def.ContractName.Equals(ContractName)) 
    { 
     return SourceProvider 
     .GetExports<IDependency>() 
     .Select(e => new Export(def.ContractName,() => new Service(e.Value))); 
    } 

    return Enumerable.Empty<Export>(); 
    } 
} 
あなたは(実際にそうな問題を引き起こすこと)あなたの Serviceタイプを [Export]する必要はありませんが、あなたは [Import]Serviceインスタンスの [ImportMany]をすることができ、あなたのコンテナを持つプロバイダに登録している場合、および SourceProviderプロパティを設定

var catalog = // create catalogs/ 
var provider = new ServiceExportProvider(); 
var container = new CompositionContainer(catalog, provider); 
provider.SourceProvider = container; 
関連する問題