使用CreationPolicy导致MEF导入问题

时间:2010-06-16 19:40:53

标签: .net mef

下面是我的问题的演示, 我想创建许多孩子,他们提到了他们的父母。

如何编写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;
}

3 个答案:

答案 0 :(得分: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唯一的上下文是合同名称(或合同类型的名称)。

我希望这会有所帮助。

答案 1 :(得分:2)

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

答案 2 :(得分:0)

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

我要做的是将Parent的CreationPolicy更改为Shared,这样它就不会再次组合,并且可以通过子项中的Import属性进行分配。不利的一面是,您的Parent1和Parent2属性实际上将是Parent的相同实例。