MEF's ImportMany in the base class imports all exports from all assembles - how to prevent that?
我正在使用MEF从几个程序集中组合导出的类型。我使用的是一个基类,它应该是
基础组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [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 {} |
大会乙:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [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 {} |
然后我在基本组件中组合所有内容:
1 2 3 4 5 6 7 8 | 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组合
我知道我可能应该为此使用依赖项注入容器,但我希望它可以与MEF有关?
你在用这种方法绕着MEF做一些奇怪的舞蹈,你基本上是多次编写基类,这将给你不同的结果,基于哪个组合最后发生。当前编写代码的方式在main中发生的组合将是最后一个设置importmany的方式,因为它发生在对baseclass的构造函数调用之后。与Ariel类似,我建议您不要在同一个对象上进行多个合成。
如果你必须对MEF做这样的事情,我可以通过以下几种方式看到它可能起作用:1)不要在构造函数中执行第二个组合,而是使用ipartimportssatisfiednotification,在onimportssatisfied中执行第二个组合,尽管在编写第二次时要注意对该方法的第二个调用。2)按照Ariel的建议执行,不要使用importMany,而只需执行getexportedValues以将该字段与其他程序集级别的目录一起设置。请记住,这仍然是一个很大的假设,即每个程序集只能有一个派生类,否则仍然会碰到重叠。3)您可以将importMany移到派生类中,并为每个派生类型(即i a dependency或ibdendency)导入一个唯一的依赖类型。4)可以使用元数据过滤特定派生类型的导入。
我不确定其中任何一个是否完美,但如果我选择一个选项,我可能会使用4的一些变体,并使用元数据在导入之间进行过滤。看看MEF如何确定其进口订单?它显示了如何排序导入,但存在类似的代码示例来过滤它们。
在另一篇文章的鼻子下写一篇文章是相当讨厌的;)。
因此,我决定手动调用container.getexportedValues,并在构造函数中自己设置属性,这样您就可以一起摆脱[importmany]。它并不是被操纵在外部的组成部分。
高温高压羚羊