More than Meets the Eye
At this point, the Managed Extensibility Framework has been demonstrated to satisfy a basic need for inversion of control. However, the market offers many solutions for dependency injection, so why would you use MEF? The truth is this: If your goal is simply inversion of control, the main advantage MEF provides is that it's part of the core framework. However, MEF provides quite a bit more than simple dependency resolution. The following sections examine these additional features.
Lazy Imports
What if you aren't sure whether you'll ever even need to use a particular component? For example, it doesn't make sense to add the overhead of instancing a new class, occupying processor and memory, for a component that never gets called. If this is your scenario, have no fear: MEF supports importing with the new Lazy construct. To ask for a lazy import, you simply flag the property as a lazy property, like this:
[Import] public Lazy<IDisplayText> LazyDisplay { get; set; }
Instead of referencing the property directly, you receive an instance of Lazy and reference the Value property instead. The class will be instantiated only when the property is accessed. If you never access the property, you won't incur the overhead of implementing the component.
Factories
Suppose you want to defer creating the implementation, but you need to create multiple independent instances? Perhaps the contract is good for only one transaction, and your component requires multiple transactions. Not a problem: MEF supplies a factory class that provides a means to create new instances on demand. Not only will the instances be provided, but their own dependencies will be satisfied as well.
[Import] public ExportFactory<IDisplayText> LazyDisplay { get; set; }
Multiple Imports
How can we satisfy the same contract in multiple ways? Our original example indicated that there might be multiple ways to satisfy a booking (via phone or Internet, for example). In some cases, you might require access to all implementations of a particular contract. MEF provides the ImportMany attribute to satisfy this need. We can bring in all exports like this:
[ImportMany] public List<IDisplayText> DisplayMethods { get; set; }
Then we can iterate the list and call each implementation.
Metadata
What if you wanted to import only certain contracts, based on some condition? If your system doesn't have access to the Internet, for example, you don't care about the implementation that books online. In that case, MEF allows you to tag exports with metadata, and you can filter the imports based on the metadata. The component still has no direct dependency on the component implementation, but can make smart decisions about the contracts with which it will interact.