The main difference is that with unity you will explicitly register each class you want to use in the composition:
var container = new UnityContainer();
container.RegisterType<IFoo,Foo>();
container.RegisterType<IBar,Bar>();
...
var program = container.Resolve<Program>();
program.Run();
In MEF on the other hand, you mark classes with attributes instead of registering them somewhere else:
[Export(typeof(IFoo))]
public Foo
{
...
}
At first sight this looks like a minor syntactic difference, but it is actually more important than that. MEF is designed to allow for the dynamic discovery of parts. For example, with a DirectoryCatalog
you can design your application in such a way that you can extend it by simply dropping new DLLs in the application folder.
In this example, MEF will find and instantiate all classes with an [Export(typeof(IPlugin))]
attribute in the given directory and passes those instances to the Program
constructor:
[Export]
public class Program
{
private readonly IEnumerable<IPlugin> plugins;
[ImportingConstructor]
public Program(
[ImportMany(typeof(IPlugin))] IEnumerable<IPlugin> plugins)
{
this.plugins = plugins;
}
public void Run()
{
// ...
}
}
Entry point:
public static void Main()
{
using (var catalog = new DirectoryCatalog(".","*"))
using (var container = new CompositionContainer(catalog))
{
var program = container.GetExportedValue<Program>();
program.Run();
}
}
To accommodate such dynamic composition scenarios, MEF has a concept of “stable composition”, which means that when it runs into a missing dependency somewhere it will simply mark the part as unavailable and will continue the composition anyway.
Stable composition can be quite useful, but it also makes it very difficult to debug a failed composition. So if you don’t need dynamic discovery of parts and “stable composition”, I would use a regular DI container instead of MEF. Unlike MEF, regular DI containers will give you clear error messages when a dependency is missing.
It might also be possible to get the best of both worlds by using a DI container which integrates with MEF, like Autofac. Use Autofac to compose the core application, and MEF for the parts which need to be dynamically extensible.