Как я могу добавить существующий экземпляр в каталог MEF? - PullRequest
4 голосов
/ 11 апреля 2011

У меня есть экземпляр объекта, и я хочу получить каталог MEF, содержащий этот экземпляр объекта, экспортированный как определенный тип интерфейса.Как я могу это сделать?

TypeCatalog здесь не кажется работоспособным, потому что (а) он создает новый экземпляр вместо использования существующего, и (б) ему требуется типиметь атрибут [Экспорт].В моем случае экземпляр происходит из системы метаданных MEF, поэтому MEF создает базовый тип, и я не могу добавить к нему атрибуты.

Насколько я могу судить, обычный совет: если выПолучив существующий экземпляр, вы должны добавить его в контейнер (например, через CompositionBatch ), а не в каталог .Но когда я добавляю этот экземпляр, я также добавляю целый набор типов AssemblyCatalog, все в одной операции.Я также хочу иметь возможность удалить все эти типы позже.Для меня более логично объединить все в AggregateCatalog.Таким образом, я могу добавить сборку и экземпляр в одну атомарную операцию и удалить их все одинаково.

Например:

// Bootstrapper code to initialize MEF:
public void Configure() {
    _selectedGameCatalog = new AggregateCatalog();
    var globalCatalog = new AggregateCatalog(_selectedGameCatalog);
    _container = new CompositionContainer(globalCatalog);
    // ... more MEF initialization ...
}

// Sometime later, I want to add more stuff to the MEF ecosystem:
public void SelectGame(Lazy<Game, IGameMetadata> entry) {
    var newCatalog = new AggregateCatalog();
    // Make the assembly available to import:
    newCatalog.Catalogs.Add(new AssemblyCatalog(entry.Value.GetType().Assembly));

    // I also want the metadata to be available to import:
    IGameMetadata metadata = entry.Metadata;
    newCatalog.Catalogs.Add(MakeCatalogFromInstance<IGameMetadata>(metadata));

    // Replace whatever game was selected before:
    _selectedGameCatalog.Catalogs.Clear();
    _selectedGameCatalog.Catalogs.Add(newCatalog);
}

Часть, которую я наденуне знаю, как это сделать "MakeCatalogFromInstance".Как я могу создать каталог, который содержит существующий экземпляр (зарегистрированный как определенный тип)?

Или, в качестве альтернативы, если я все делаю неправильно, есть ли лучший способ подключить весь каталог и существующего экземпляра одновременно в MEF, с возможностью позже отключить их все и заменить чем-то другим?

Ответы [ 2 ]

1 голос
/ 15 ноября 2012

За процветание ...

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

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

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

1 голос
/ 11 апреля 2011

Я думаю, что, вероятно, лучше добавить типы в каталог, а затем добавить экземпляр в контейнер.

Каталоги содержат определения частей.Определения деталей используются для создания деталей.(Типы для этого ComposablePartDefinition и ComposablePart.) Таким образом, вы можете теоретически написать свой собственный каталог и определение детали, которое всегда возвращает деталь, соответствующую экземпляру, когда вызывается CreatePart.Но каталоги на самом деле не были предназначены для такого использования.

...