我正在使用MEF从几个程序集中组合导出的类型。我正在使用一个基类,它应该是派生类中指定的ImportMany
依赖项。它看起来像这样:
基础组装:
public abstract class BaseClass
{
[ImportMany(typeof(IDependency)]
public IEnumerable<IDependency> Dependencies { get; private set; }
protected BaseClass()
{
var catalog = GetCatalog();
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
protected abstract ComposablePartCatalog GetCatalog();
}
汇编A:
[Export(typeof(BaseClass))]
public class MyA : BaseClass
{
protected override ComposablePartCatalog GetCatalog()
{
return new AssemblyCatalog(Assembly.GetExecutingAssembly());
}
}
[Export(typeof(IDependency)]
public class DependencyA1 : IDependency {}
[Export(typeof(IDependency)]
public class DependencyA2 : IDependency {}
大会B:
[Export(typeof(BaseClass))]
public class MyB : BaseClass
{
protected override ComposablePartCatalog GetCatalog()
{
return new AssemblyCatalog(Assembly.GetExecutingAssembly());
}
}
[Export(typeof(IDependency)]
public class DependencyB1 : IDependency {}
[Export(typeof(IDependency)]
public class DependencyB2 : IDependency {}
然后我在基础组件中编写所有内容:
static void Main(string[] args)
{
DirectoryCatalog catalog = new DirectoryCatalog(path, "*.dll");
var container = new CompositionContainer(catalog);
IEnumerable<BaseClass> values = container.GetExportedValues<BaseClass>();
// both BaseClass instances now have 4 Dependencies - from both Assemby A and Assembly B!
}
我遇到的问题是,当我使用MEF同时撰写MyA
和MyB
时,每个都包含来自两个程序集的导出的IDependency
- !我只希望MyA
包含导出DependencyA1
和DependencyA2
,与MyB
相同。
我知道我可能应该使用依赖注入容器,但是我希望可以使用MEF吗?
答案 0 :(得分:1)
在另一个作品的鼻子下做一个作品非常讨厌;)。
所以我决定手动调用container.GetExportedValues并在构造函数中自己设置属性,这样你就可以一起摆脱[ImportMany]了。 它不会被外部构图所操纵。
HTH 爱丽儿
答案 1 :(得分:1)
你正在围绕MEF做一些奇怪的舞蹈,这种方法你基本上是多次编写BaseClass,它将根据最后发生的合成给你不同的结果。代码当前编写的方式是在Main中发生的组合将是最后设置ImportMany的组合,因为这是在构造函数调用BaseClass之后发生的。与Ariel类似,我建议你不要在同一个对象上做多个作文。
如果您必须使用MEF做这样的事情,我可以通过以下几种方式看到它可能有效: 1)不要在构造函数中执行第二个组合,而是使用IPartImportsSatisfiedNotification并在OnImportsSatisifed中执行第二个组合,尽管在第二次组合时要注意第二次调用此方法。 2)执行Ariel建议并且不使用ImportMany,而只是使用GetExportedValues将该字段设置为其他程序集级别目录。请记住,这仍然是一个很大的假设,即每个程序集只会有一个派生类,否则你仍会遇到重叠。 3)您可以将ImportMany移动到派生类中,并为每个派生类型(即IADependency或IBDendency)导入唯一的依赖关系类型。 4)您可以使用元数据来过滤特定派生类型的导入。
我不确定这些是否完美,但如果我选择一个选项,我可能会选择#4的一些变体,并使用元数据来过滤导入。请参阅How does MEF determine the order of its imports?,其中显示了如何订购导入,但存在类似的代码示例以过滤它们。