1

I'm using MEF in my WPF application, and I'm not sure if my exports are not making it into the container because of the way I'm exporting them, or because of the way I'm querying the container.

Here's my object hierarchy:

public interface ICommonInterface
{ }

[InheritedExport]
public abstract class CommonBaseClass<T> : ICommonInterface 
{ }

public Class1 : CommonBaseClass<Class1>
{ }

public Class1 : CommonBaseClass<Class2>
{ }

I'm using the implementation of T in the base class for reasons outside the scope of the question; that's why it's there. If I get rid of the generics on CommonBaseClass, and it's inherited classes, I can get the exports from my container as thus:

var container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
var exports = container.GetExportedValues<CommonBaseClass>();

What I want to do, is to get the generics version of exports:

var exports = container.GetExportedValues<CommonBaseClass<ICommonInterface>>();

There aren't any errors, just no results.

Random
  • 1,896
  • 3
  • 21
  • 33

3 Answers3

0

MEF isn't quite the same as a IoC container. MEF does not do inheritance exports. You need to add an attribute

[Export(type(CommonBaseClass<ICommonInterface>))] 
Aron
  • 15,464
  • 3
  • 31
  • 64
  • Removing the other exports, and adding this to Class1 (using "typeof" instead of "type"), I get a casting error... Cannot cast the underlying exported value of type 'Class1 (ContractName="CommonBaseClass(ICommonInterface)")' to type 'CommonBaseClass`1[ICommonInterface]' – Random Mar 04 '13 at 16:40
0

Your code doesn't compile.

If what you meant was:

public interface ICommonInterface
{ }

[InheritedExport]
public abstract class CommonBaseClass<T> : ICommonInterface 
{ }

public class Class1 : CommonBaseClass<Class1>
{ }

public class Class2 : CommonBaseClass<Class2>
{ }

Then you can get an export with:

var exports = container.GetExportedValues<CommonBaseClass<Class1>>();
Panos Rontogiannis
  • 4,154
  • 1
  • 24
  • 29
0

MEF does not provide support for "open generics" out of the box. There is a MefContrib project that can help you with that http://mefcontrib.codeplex.com/wikipage?title=Generic%20Catalog

What I'd do in this situation though is use the [InheritedExport] attribute on your ICommonInterface rather than the CommonBaseClass<T>. Like this:

[InheritedExport]
interface ICommonInterface {}

public abstract class CommonBaseClass<T> : ICommonInterface { }

public class Class1 : CommonBaseClass<Class1> { }

public class Class2 : CommonBaseClass<Class2> { }

Then you are in a position to do this:

var exports = container.GetExportedValues<ICommonInterface>();

Let's say you have another class which also implements ICommonInterface and you don't want to pull that into your container. In that case, you can use the [PartNotDiscoverable] attribute:

[PartNotDiscoverable]
public class Class3 : ICommonInterface {}
ChrisO
  • 5,068
  • 1
  • 34
  • 47
  • The problem with that approach is that I only get the properties exposed by the interface. I also tried an additional CommonBaseClass to do the inheriting from in the hierarchy, but that had the same problem.The type argument wouldn't be a part of either of those solutions. – Random Mar 01 '13 at 02:27
  • @ChrisO MEF2, the version shipped with .NET Framework 4.5 does support open generic parts. It was the previous version of MEF that didn't support them. http://blogs.msdn.com/b/bclteam/archive/2011/10/27/what-s-new-in-mef-version-2-preview-4.aspx – Panos Rontogiannis Mar 01 '13 at 07:47
  • I'm using 4.5, so how can I get my sample to work using open generics? – Random Mar 04 '13 at 15:49