2010-06-16 104 views
0

下面是我的问题的演示, 我想创建许多孩子,其中有一个参考他们的父母。MEF导入问题与CreationPolicy

如何编写import属性以获取父引用而不是创建新的父实例?

public partial class MainPage : UserControl 
{ 
    [Import(typeof(Parent))] 
    public Parent Parent1 { get; set; } 

    [Import(typeof(Parent))] 
    public Parent Parent2 { get; set; } 


    public MainPage() 
    { 
     InitializeComponent(); 
     CompositionInitializer.SatisfyImports(this); 
     Parent1.name = "p1"; 
     Parent2.name = "p2"; 
    } 
} 

[PartCreationPolicy(CreationPolicy.NonShared)] 
[Export(typeof(Parent))] 
public class Parent 
{ 
    [Import(typeof(Child))] 
    public Child Child1 { get; set; } 

    [Import(typeof(Child))] 
    public Child Child2 { get; set; } 

    public string name; 
} 


[PartCreationPolicy(CreationPolicy.NonShared)] 
[Export(typeof(Child))] 
public class Child 
{ 
    //how to write the import attribute 
    public Parent Parent { get; set; } 
    public string name; 
} 

回答

0

你可能会遇到的问题,因为在MEF的组合机制是递归的,它通过以图形的所有对象。你在这里做的是试图将一个项目导入另一个项目,另一个项目将尝试导入第一个项目。您将看到的另一个问题是您指定了NonShared的CreationPolicy,这意味着将为每个导入创建一个新实例。结合递归问题,它是一个完美的内存/性能灾难等待发生;)

我会做什么,是将Parent的CreationPolicy改为Shared,这样它不会再组成第二次,也可以是通过子项中的Import属性进行分配。缺点是你的Parent1和Parent2属性实际上是Parent的同一个实例。

2

如果我理解你的问题,你不能在这里进行导入,因为MEF没有你在这里寻找的上下文来执行它。我的建议是将Child.Parent属性设置为在Parent中导入的Child。也许在Child1/Child2设置器中将Parent属性设置为此。

3

MEF最适合将单独的模块链接在一起。它有点矫枉过正,将一个意图处于同一逻辑层次结构中的对象组合起来。

我会打扮的Child属性来设置父:

[PartCreationPolicy(CreationPolicy.NonShared)] 
[Export(typeof(Parent))] 
public class Parent 
{ 
    private Child _child1; 
    private Child _child2; 

    [Import(typeof(Child))] 
    public Child Child1 
    { 
     get { return _child1; } 
     set { _child1 = value; _child1.Parent = this; } 
    } 

    [Import(typeof(Child))] 
    public Child Child2 
    { 
     get { return _child2; } 
     set { _child2 = value; _child2.Parent = this; } 
    } 

    public string name; 
} 

这样,只要进口满足创建Parent类的儿童,Child班都会有自己Parent引用设置为好。这种链接引用的方式是MEF友好和相当标准的。只是不要在两个方向上做(如果你有一对一的关系),因为你会得到一个无限循环。

您似乎在设计范围之外使用MEF。在MEF中,对于每个合同名称,您可以拥有一个单一引用或多个单一类型的引用。 MEF唯一的上下文是合同名称(或合同类型的名称)。

我希望这会有所帮助。