A desktop application using MEF
imports many \'ServiceProviders\'. Each part (ServiceProvider) is a class inside a separate DLL.
All DLLs are in \'Plugin\" folder w
When MEF sees an import of the type ExportFactory
, it treats this in a special way. Instead of looking literally for an ExportFactory
export, it looks instead for a IFoo
export and magically generates a factory for that type.
Your mistake is that you expect this magic to also automatically work for your own alternative to ExportFactory
which you called SrviceProviderFactory
. This is not true. When you import SrviceProviderFactory
somewhere, MEF literally looks for an export of that type.
The straightforward solution is to give it this export. Manually export a factory for each IServiceProvider implementation. For example, if you have a FooServiceProvider
:
public class FooServiceProvider : IServiceProvider
{
public FooServiceProvider(Dependency dependency)
{
...
}
}
Then you also need to have a FooServiceProviderFactory:
[Export(typeof(IServiceProviderFactory))]
[ExportMetaData("foo", "bar")]
public class FooServiceProviderFactory : IServiceProviderFactory
{
public IServiceProvider CreateServiceProvider(Dependency d)
{
return new FooServiceProvider(d);
}
}
And then your importer can select the right factory based on metadata:
public class FactoryUser
{
[ImportMany]
public Lazy>[] Factories
{
get;
set;
}
public void DoSomething()
{
var factory = Factories.First(x => x.Metadata["foo"] == "bar").Value;
var serviceProvider = factory.CreateServiceProvider(someDependency);
...
}
}
The annoying thing here is that for each service provider implementation, you also need to create and export a factory implementation. You can save work by creating a common factory base class (like your SrviceProviderFactory
) but you still have to derive specific classes because you can't use generic type parameters in MEF exports. update: I believe .NET 4.5 now supports exporting open generic types.
That's why I already suggested you export Func instead, but apparently you didn't like that answer.
You could also try to replicate the ExportFactory
magic. This is possible but a very advanced use case of MEF. If you want to do that I suggest you take a look at the MEF sources of ExportFactoryProvider
to see how to build your own implementation with support for parameters.