最近,在我的WPF应用程序中使用MEF时遇到了一个问题。我创建了几个类,如下所示。Part
类型被设置为CreationPolicy.NonShared
,这样将有2个不同的对象导入到ClassA和ClassB中。
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class Part
{
public int Id { get; set; }
}
[Export]
public class ClassA
{
[Import]
public Part PartA { get; set; }
}
[Export]
public class ClassB
{
[Import]
public Part PartB { get; set; }
}
我写了一小段代码来描述我的问题,如下所示。
[Export]
class Program
{
[Import]
public ClassA A { get; set; }
[Import]
public ClassB B { get; set; }
[ImportMany(AllowRecomposition = true)]
public IEnumerable<Part> AllParts { get; set; }
static void Main(string[] args)
{
var catalog = new AssemblyCatalog(typeof(Program).Assembly);
var container = new CompositionContainer(catalog);
var prog = container.GetExportedValue<Program>();
foreach (var part in prog.AllParts)
{
// Do something for Part instances.
// I want to get all Part instances created by MEF which have imported to ClassA and ClassB.
// However, it comes a list with a brand new Part instance.
}
}
}
所以会有ClassA,ClassB和一系列Part实例导入到Program对象中。实际上,我想得到的是MEF容器创建的所有Part实例。然而,它返回了一个全新的Part实例列表。
我知道这可能是因为我在Part类中指定了CreationPolicy.NonShared。但是,即使我尝试在container.Catalog.Parts中查找它们,我也只找到了一个Part实例。这让我感到困惑。根据我的理解,容器应该持有它创建的所有对象的引用,因为我已经指定了AllowRecomposition = true。我找到了一篇文章来证明这一点。它说:
容器和部件引用
我们认为 .Net 垃圾回收器是可靠的清理工具,但我们也需要提供一个具有确定性行为的容器。因此,容器不会保留对其创建的部件的引用,除非以下情况之一成立:
- 该组件标记为共享
- 该组件实现IDisposable接口
- 一个或多个导入被配置为允许重新组合
对于这些情况,将保留一个部件引用。结合您可以拥有非共享的部件并继续请求这些部件的事实,内存需求可能很快成为一个问题。为了缓解这个问题,您应该依赖下面两个主题中讨论的以下策略之一。
所以我有2个问题:
为什么在容器中找不到超过一个
Part
类型的实例?如何在我的演示中获取所有导出的
Part
实例?
ImportMany
来完成。)也许如果你能给我们更多关于你想要实现什么(例如,为什么你需要那些实例),我们可以给你更好的建议。 - Venemo