Search code examples
mef

MEF Export derived classes ans new instances


I have a base class and a derived class and I want to export for types derived from either.

So like this

public class ClassA { }
public class ClassB : ClassA { }

I need to load types derived from ClassA but also types derived from ClassB.

var registration = new RegistrationBuilder();

registration.ForTypesDerivedFrom<ClassA>()
    .Export<ClassA>();

registration.ForTypesDerivedFrom<ClassB>()
    .Export<ClassB>();

var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog(".", registration));
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly(), registration));

container = new CompositionContainer(catalog);
container.SatisfyImportsOnce(this, registration);

I think the problem is that when exporting ClassA derived types it also exports ClassB types which is obvious and is the functionality that I am looking for. But it means that the ClassB imports aren't exported as independent objects, rather being the same ones as those imported as ClassA types. If I don't specifically export the ClassB then any imports using them fail.

I may be trying to do something stupid to try and solve my problem here that MEF isn't liking? I have looked at making the MEF imports non-singleton but that might break things in my imports.


Solution

  • In your given example only ClassB (with the export definition of classA) is exported as a MEF part. As Panos already mentioned, ForTypesDerivedFrom does not export the base class.

    You can do something like this:

    var registration = new RegistrationBuilder();
    registration.ForTypesDerivedFrom<ClassA>().Export();
    registration.ForType<ClassA>().Export();
    

    This will export all derived classes of ClassA (also ClassB with ClassB contract and not with ClassA) and separately ClassA. Additionally if you want to hide the base part but still want to use imports in this class you can add the [PartNotDiscoverable] attribute to your base class.