Проблема импорта MEF с CreationPolicy - PullRequest
0 голосов
/ 16 июня 2010

ниже - демонстрация моей проблемы, я хотел бы создать много дочерних, которые имеют ссылку на своего родителя.

Как написать атрибут импорта для получения родительской ссылки вместо создания нового родителяэкземпляр?

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 ]

3 голосов
/ 03 марта 2011

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, - это имя контракта (или название типа контракта).

Надеюсь, это поможет.

2 голосов
/ 18 июня 2010

Если я понимаю ваш вопрос, вы не можете выполнить импорт здесь, потому что MEF не имеет контекста, который вы ищете здесь, чтобы сделать это. Я бы предложил установить свойство Child.Parent для Child, который импортируется в Parent. Возможно, в установщике Child1 / Child2 просто установите свойство Parent на это.

0 голосов
/ 18 июня 2010

Скорее всего, у вас возникнут проблемы, потому что механизм компоновки в MEF рекурсивен, он проходит через все объекты, которые будут отображены.Здесь вы пытаетесь импортировать один элемент в другой, а другой пытается импортировать первый тип.Другая проблема, с которой вы столкнетесь, заключается в том, что вы задаете CreationPolicy для NonShared, что означает, что для каждого импорта будет создан новый экземпляр.Сочетая это с проблемой рекурсии, мы ожидаем, что произойдет совершенная катастрофа с памятью и производительностью;)

Что бы я сделал, это изменил родительский CreationPolicy на Shared, чтобы он не создавался во второй разможет быть назначен через атрибут импорта в дочернем элементе.Недостатком является то, что ваши свойства Parent1 и Parent2 фактически будут одним и тем же экземпляром Parent.

...