0

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?

Community
  • 1
  • 1
Mike-E
  • 2,477
  • 3
  • 22
  • 34

1 Answers1

2

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();
Metro Smurf
  • 37,266
  • 20
  • 108
  • 140
  • Hi @Metro-Smurf thank you for your answer. I do realize that the method is what you describe and not a delegate. I am wanting to make a delegate out of this method, as such: `Func @delegate = new Func( factory.Create );` and then register __that__ as the export. Make sense? I also realize that your answer will get me a direct export of an `IFactory`. However, that is not what I am looking for. Please refer to my question to see the exact exports that I desire. See: magic. :) If I request a `Class` object, I am actually calling the `factory.Create` somewhere. Thanks again! – Mike-E Feb 29 '16 at 08:30
  • I probably mis-understood the question; sorry about that. I can take a closer look later today, but a couple of things to consider: 1. Use a property export which will simply export whatever is being returned from a property. 2. Give this a read: [Resolving closed types with MEF by Mark Seemann](http://blog.ploeh.dk/2011/03/14/ResolvingclosedtypeswithMEF/) Again, apologies for mis-understanding. – Metro Smurf Feb 29 '16 at 14:41
  • No worries! We've all been there. :) I am indeed aware of Mr. Seemann's post, but was looking for another route here if possible. Something that doesn't require me to specify types. I simply want to `[Export]` an `IFactory` and MEF "just knows" how to call its `Create` method and return the instance. In Unity there is an `InjectionFactory` that can be used when registering a type. I am looking for something comparable for MEF 2. After digging, I did [find this](https://github.com/MefContrib/MefContrib/blob/master/src/MefContrib/Hosting/FactoryExportProvider.cs) but it is MEF 1. – Mike-E Feb 29 '16 at 21:19