Custom 'ExportFactory'

A desktop application using MEF imports a variety of "ServiceProviders". Each part (ServiceProvider) is a class inside a separate DLL. All DLL files are located in the "Plugin" folder, which is used by the desktop application.

Since I needed new instances of my parts, ExportFactory was the best choice. The problem is that my parts have constructors. I need to pass some parameters to the constructor of a part that is not supported by ExportFactory (MEF2, Preview2).

I need something like this:

 // Each part has its own dependency Dependency dependency = LoadDependency(myPart.Metedata["Name"]); // Injecting dependency into part constructor myPart.CreateExport(dependency); 

I do not need to import anything from my side.

An example project (with a constructor without parameters) can be found here .

+6
c # export factory mef
source share
1 answer

When the MEF sees an import of type ExportFactory<IFoo> , it considers this in a special way. Instead of looking literally at the ExportFactory<IFoo> export, it looks instead of the IFoo export and magically generates a factory for this type.

Your mistake is that you expect this magic to automatically work for your own alternative ExportFactory , which you called SrviceProviderFactory . It is not true. When you import SrviceProviderFactory<IFoo,IFooMetadata> somewhere, MEF literally looks for an export of this type.

A simple solution is to give it this export. Manually export the factory for each implementation of IServiceProvider. For example, if you have a FooServiceProvider :

 public class FooServiceProvider : IServiceProvider { public FooServiceProvider(Dependency dependency) { ... } } 

Then you will also need 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 choose the right factory based on metadata:

 public class FactoryUser { [ImportMany] public Lazy<IServiceProviderFactory,IDictionary<string,object>>[] Factories { get; set; } public void DoSomething() { var factory = Factories.First(x => x.Metadata["foo"] == "bar").Value; var serviceProvider = factory.CreateServiceProvider(someDependency); ... } } 

It’s annoying that for each service provider implementation you also need to create and export a factory implementation. You can save your work by creating a common factory base class (for example, your SrviceProviderFactory ), but you still have to output certain classes because you cannot use type type parameters in an MEF export. update . I'm sure .NET 4.5 now supports exporting open generic types.

That's why I already suggested you export Func instead , but it seems you didn’t like this answer.

You can also try to reproduce the magic of ExportFactory . It is possible, but a very advanced use case for MEF. If you want to do this, I suggest you take a look at the sources of the MEF ExportFactoryProvider to learn how to create your own implementation with parameter support.

+5
source share

All Articles