Есть ли способ в MEF для составного объекта, чтобы получить указатель на используемый ObjectComposer? - PullRequest
1 голос
/ 10 февраля 2011

пытается создать нетривиальное приложение MEF.

Интересно - есть ли способ для составляемого объекта получить указатель на ObjectComposer, использованный для его создания?

Сценарий таков, что объект может создавать внутренние композиции. Я могу нажать все ссылки до сих пор с помощью атрибутов IMPORT для свойств или конструктора, но мне не хватает способа для составного объекта получить композитор объекта (чтобы он мог создать субкомпозитор для своих внутренних элементов).

Какой-нибудь стандартный / передовой метод?

Ответы [ 2 ]

1 голос
/ 10 февраля 2011

Я предполагаю, что под "ObjectComposer" вы подразумеваете контейнер MEF. Мне не известен ни класс, ни концепция с именем ObjectComposer.

( edit : в документации CompositionContainer теперь явно упоминается, что вы не должны помещать контейнер в себя.

В коде запуска вашего приложения контейнер может сам себя зарегистрировать:

CompositionContainer container = new CompositionContainer(...);
container.ComposeExportedValue<ExportProvider>(container);

Тогда вы можете импортировать его куда угодно:

[Import]
public ExportProvider Composer { get; set; }

Тем не менее, здесь вы запрашиваете Сервисный локатор, который имеет определенные недостатки . Лучше импортировать более конкретные сервисы, например, абстрактную фабрику.

ExportFactory также могут быть полезны здесь, но это не вошло в выпуск .NET 4. Вам придется использовать последнюю версию codeplex MEF , если вы хотите попробовать это.

0 голосов
/ 10 февраля 2011

Вот как я это делаю:

Многие мои экспортеры импортируют IMain.

[Import(typeof(IMain))]
public IMain Main { get; set; }

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

public interface IMain
{
    ICompositionService CompositionService { get; set; }
    EventPublisher Events { get; set; }
    // more...
}

Исходная композиция выглядит следующим образом:

AggregateCatalog Catalog = new AggregateCatalog();
Catalog.Catalogs.Add(new DirectoryCatalog(Application.StartupPath));
CompositionContainer Container = new CompositionContainer(Catalog);
this.CompositionService = Container;  // <- here I'm setting the IMain composition service
Container.ComposeParts(this);

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

MainPanel discoverPanel = new MainPanel();
Main.CompositionService.SatisfyImportsOnce(discoverPanel);
discoverPanel.Show();
...