1

私は次のような状況にあります。アセンブリAIには次のものがあります。

public class Service : IService
{
   private readonly IDependency dependency;

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

アセンブリでは、BとCIの実装が異なりますIDependency

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

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

Serviceエクスポートされたそれぞれのインスタンスを作成するようにMEFに指示するにはどうすればよいIDependenciesですか?

4

2 に答える 2

2

MEFは、これをそのままではサポートしていません。2つのオプションがあります。

  1. [ImportMany(typeof(IService))]おそらく、すべてのサービスインスタンスをインポートするためにどこかで行うことを計画していました。ServiceProvider代わりに、次のように実装されたオブジェクトをインポートできます。

    [Export]
    public class ServiceProvider
    {
        [ImportMany]
        public IEnumerable<IDependency> Dependencies { get; set; }
    
        public IEnumerable<IService> GetServices()
        {
           return Dependencies.Select(x => new Service(x));
        }
    }
    
  2. 独自のエクスポートプロバイダーの実装でMEFを拡張できます。私は、[ExportMany]そのようなカスタムエクスポートプロバイダーによって認識される属性を追加するというアイデアをいじくりまわしました。動作しているように見えますが、概念実証にすぎません。https://bitbucket.org/wcoenen/mefexportmany/を参照してください。

于 2012-04-15T19:50:24.993 に答える
1

Wim が言ったように、これはすぐに使用できるネイティブ サポートではありません。このようなことができるようにしたい場合:

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

ServiceProvider...ファクトリ( Wimによる詳細など)を使用せずに、エクスポートプロバイダーが機能します。たとえば、次のようになります。

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>();
  }
}

[Export]タイプを指定する必要はありませんService(実際には問題が発生する可能性があります) が、コンテナーでプロバイダーに登録し、プロパティを設定している場合は、[Import]インスタンスを指定できます。[ImportMany]ServiceSourceProvider

var catalog = // create catalogs/
var provider = new ServiceExportProvider();
var container = new CompositionContainer(catalog, provider);
provider.SourceProvider = container;
于 2012-04-16T08:59:46.637 に答える