tags:

views:

26

answers:

2

below is the demo of my problem, I'd like to create many child which have a reference to their parent.

How to write the import attribute to get the parent reference instead of create a new parent instance?

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;
}
A: 

You'll likely run into problems because the composition mechanism in MEF is recursive, it goes through all the objects to be graphed. What you're doing here is attempting to import one item into another, where the other will attempt to import the first type. The other issue you will be seeing is that you're specifying a CreationPolicy of NonShared, which means a new instance will be created for each of the imports. Combining that with the recursion problem, its a perfect memory/performance disaster waiting to happen ;)

What I would do, is change the Parent's CreationPolicy to Shared, that way it won't be composed a second time and can be assigned through the Import attribute in a child. The downside to that is that your Parent1 and Parent2 properties will in fact be the same instance of Parent.

Matthew Abbott
A: 

If I understand your question you cannot do an Import here because MEF does not have the context you are looking for here to do it. My suggestion would be to set the Child.Parent property on the Child that gets imported in the Parent. Perhaps in the Child1/Child2 setter just set the Parent property to this.

Wes Haggard