我有以下情况。在程序集A中,我有以下内容:
public class Service : IService
{
private readonly IDependency dependency;
public Service(IDependency dependency)
{
this.dependency = dependency;
}
}
在程序集B和C中,我有IDependency
的不同实现:
[Export(typeof(IDependency)]
public class Dependency1 : IDependency { }
[Export(typeof(IDependency)]
public class Dependency2 : IDependency { }
如何指示MEF为每个导出的Service
创建IDependencies
的实例?
答案 0 :(得分:2)
MEF不支持开箱即用。您有两种选择:
据推测,您计划在某个地方执行[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));
}
}
您可以使用自己的导出提供程序实现来扩充MEF。我已经玩弄了添加[ExportMany]
属性的想法,该属性可以被这样的自定义导出提供程序识别。它似乎工作,但它只是一个概念的证明。请参阅https://bitbucket.org/wcoenen/mefexportmany/。
答案 1 :(得分:1)
正如Wim所说,这不是开箱即用的原生支持。如果你想做这样的事情:
[ImportMany]
public IEnumerable<Service> _services { get; set; }
...没有使用工厂(例如Wim详述的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>();
}
}
您不需要[Export]
Service
类型(实际上可能会导致问题),但[Import]
和[ImportMany]
Service
如果您已使用容器向提供者注册,则设置SourceProvider
属性:
var catalog = // create catalogs/
var provider = new ServiceExportProvider();
var container = new CompositionContainer(catalog, provider);
provider.SourceProvider = container;