Соглашения Microsoft.Composition (MEF2) и открытые дженерики

У меня есть тип

public class Queue<T> : IQueue
{
....
}

Я могу экспортировать это используя

[Export(typeof(Queue<>))]

что позволит мне импортировать с

[Import] Queue<StockController>
[Import] Queue<FileController>

Тем не менее, я хотел бы импортировать эти типы как

[ImportMany] IQueue

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

Я хочу использовать соглашения для предоставления этих экспортов и добавлять метаданные к каждому из них. Я в порядке с тем, как добавить метаданные, но я не уверен, как обеспечить экспорт. По сути, я хочу что-то вроде (псевдокод)

conventions.
    ForType(typeof(Queue<StockContoller>)).Export<IQueue>(x => x.AddMetadata("Name", "StockQueue")
    ForType(typeof(Queue<FileContoller>)).Export<IQueue>(x => x.AddMetadata("Name", "FileQueue")

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

Есть ли способ сделать это?

1 ответ

Решение

Оказывается, решение состоит из двух частей. Сначала добавьте деталь в контейнер, затем определите соглашение. Вот метод расширения, который достигает этого.

public static ContainerConfiguration WithQueue(
            this ContainerConfiguration config,
            Type queueType,
            string queueName)
        {
            var conventions = new ConventionBuilder();

            conventions
                .ForType(queueType)
                .Export<IQueue>(x => x.AddMetadata("QueueName", queueName));

            return config.WithPart(queueType, conventions);
        }

Использование:

CompositionHost container =
    new ContainerConfiguration()
    .WithQueue(typeof(ControllerQueue<StockMovementController>), "StockMovements")
    .WithAssemblies(GetAssemblies())
    .CreateContainer();

(где GetAssemblies() возвращает сборки для сборки контейнера)

Другие вопросы по тегам