When organizing a project where should I put the provider interfaces which are used in MEF? Currently I just have them in the same project as everything else but it seems like it might desirable for me to extract them into a separate dll such that it was a very small dll and would easily be linked to by others attempting to write extensions. What is good practise for this?
As with any plug-in/extension model, you should put your "contracts" (the interfaces a plug-in author should be implementing) in an assembly separate from your application.
That way you can make that assembly available to plug-in authors without having to give them the entire application - useful if it's a commercial app that you need to license separately.
MEF Preview 5 introduces the ability to export an interface (ie add an [Export] attribute to an interface) such that any implementor of that interface is automatically exported. That means that plug-in authors don't even need to know about MEF - they just implement your interface and they're automatically a MEF extension.
Originally MEF was going to implement duck typing, which would mean you wouldn't need a common assembly, but apparently this proved too difficult.
I'm putting them all in a common assembly, along with some useful abstract base classes that can be used to help implement the interfaces.
I was also having same question and wanted to see an example where Contracts are defined in one project, multiple implementations are defined in other projects and a separate consumer projects which uses contract and has extension folder where implementation dll's can be simply copied and is available to the consumer application without any code changes. So I tried writing a simple Hello World kind of application and posted at my blog. Hope you might find it useful. I have also posted the source code (in C#).
http://ppsinfo.blogspot.com/2009/11/managed-extensibility-framework-mef.html
Actually there is new feature in .NET 4.0 called type equivalence that can accomplish this. With this feature you can haave two different interfaces in different contract assemblies that tell the CLR they are the same. Because it is low-level, MEF can work with it fine.
A few caveats:
- Other than framework types, only custom interfaces are supported.
- Custom generic interfaces are not supported.
- Matching requires a guid on both interfaces :-(
You can read more about it here: http://msdn.microsoft.com/en-us/library/dd997297%28VS.100%29.aspx. The documentation will say it's for COM, but you can use it for managed code as well.