How Can I Export a Factory and/or its Method in MEF 2?

926 views Asked by At

I am looking into MEF 2 (Microsoft.Composition) and am looking to integrate it with my existing code base.

My current codebase has an IFactory interface with a simple signature:

public interface IFactory<T>
{
    T Create();
}

I would like to register my factories so that if I do an export on a factory, it is registered as a Func<T> for the factory's T output. So something like this:

[Export]
public class Factory : IFactory<Class>
{
    public Class Create() => new Class();
}            

Will return a new Class instance and a reference to the Create method (as a Func<Class> delegate) with the following code:

using ( var container = new ContainerConfiguration()
    // ... magic missing here.
    .CreateContainer() )
{
    var instance = container.GetExport<Class>(); // instance is created from the Factory.Create above.
    var factory = container.GetExport<Func<Class>>(); // this is a reference to the Factory.Create delegate defined above.
}

I did see this question, but it doesn't seem to apply for MEF 2. All sorts of things are different now, but seems much more lightweight/streamlined (as advertised!).

Is it possible to achieve what I am looking to do with MEF 2?

1

There are 1 answers

3
Metro Smurf On

public Class Create() => new Class(); is not a delegate. In C# 6 this is known as an Expression-bodied member function.

The following 2 statements are equivalent in C# 6:

// Expression-bodied member function
public MyClass Create() => new MyClass();

// standard member function
public MyClass Create()
{
    return new MyClass();
}

As far as resolving IFactory<Class> and then using the factory, simply decorate your factory with the type to export and use as needed:

[Export( typeof( IFactory<MyClass> ) )]
public class Factory : IFactory<MyClass>
{
    public MyClass Create() => new MyClass();
}

After the container has been built up, the resolution is simply:

var factory = container.GetExport<IFactory<MyClass>>();

MyClass mc = factory.Create();