我正在使用MEF来编写来自几个程序集的导出类型。我正在使用一个基类,它应该是派生类中指定的ImportMany
依赖项。它看起来是这样的: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();
}
议会答:
[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
-ies从两个组件!我只想要MyA
包含出口DependencyA1
和DependencyA2
,与MyB
相同。
我知道我可能应该为此使用依赖注入容器,但我希望可以使用MEF吗?
只是一些注意事项 - 用构造函数做构图 - 我已经看到了很多,这不是一个好设计的想法。建议您的应用程序的一个部分处理与组合容器有关的所有事情,这就是所谓的* CompositionRoot *。理想情况下,您的组件应设计为不受任何扩展性或IoC容器的影响,因此您可以独立构建和测试它们。为了做到这一点,虽然旋转一个'CompositionContainer'的新实例相对便宜,但编目创建可能很昂贵。 –
另一点需要考虑的是,您正在从构造函数调用虚拟方法,这意味着您不能再保证您的'BaseClass'构造函数将完成,因为它现在依赖于回调函数的继承层次结构。如果你的'override'方法试图使用你的子类类型的实例成员 - 你最终可能抛出'NullReferenceException'实例,因为这些实例成员可能还没有被初始化。 –
@MatthewAbbott RE构造函数中的虚拟调用,你是对的,这只是为了这个例子。在我的“真实”应用程序中,我没有从构造函数调用虚拟方法。 –