Microsoft.Composition (MEF2) Conventions and Open Generics

1.2k views Asked by At

I have a type

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

I can export this using

[Export(typeof(Queue<>))]

which will enable me to import with

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

However, I would like to import these types as

[ImportMany] IQueue

which doesn't seem possible without creating concrete types for each queue.

I want to use conventions to provide these exports, and add metadata to each one. I'm fine with how to add the metadata, but I'm not sure how to provide the exports. Essentially what I want is something like (pseudo-code)

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

but this won't work unless I actually create concrete types for each queue, which is what I don't want to have to do.

Is there a way to do this?

1

There are 1 answers

0
bornfromanegg On BEST ANSWER

Turns out the solution is two parts. First, add the part to the container, then define the convention. Here's the extension method that achieves this.

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);
        }

Usage:

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

(where GetAssemblies() returns the assemblies to build the container from)