In the three months that have passed since the last release, we’ve been very busy making final adjustments to get closer to RTM.
In this post I’ve summarized the biggest changes between the Preview 5 and Preview 6 releases.
The highlights are:
You can download MEF Preview 6 from the CodePlex site.
With this release comes an early preview of our Silverlight plans. The included solution MEFSL.sln can be used to build MEF binaries that target the newly-released Silverlight 3.
Those familiar with the full-framework MEF won’t see many differences in the Silverlight build as it stands today. We aim to have some exciting new features in the eventual release, but for now the APIs are the same apart from changes required because of the different environment.
DirectoryCatalog is not available in the Silverlight version. Instead, this is replaced by PackageCatalog.
This API is tentative and will very probably change in a future preview.
There’s a new sample called PictureViewer that demonstrates some aspects composition in a Silverlight application.
One of the first things you’ll notice when moving to the new build is that the System.ComponentModel.Composition.Export<T> and Export<T, TMetadata> types are gone.
In their place, MEF now recognizes the System.Lazy<T> and Lazy<T, TMetadta> types.
Functionally these types match the old ones, however:
The System.ComponentModel.Composition.ExportCollection<T> type has also been removed. In its place, use IEnumerable<Lazy<T>>, or Lazy<T>.
ImportManyAttribute is now required for all collection imports.
PartExportsInheritedAttribute has been removed. The new mechanism separates inheritable exports from non-inheritable exports.
Exports declared using the ExportAttribute are never inherited.
Exports declared using the InheritedExportAttribute will be exposed by sub-classes of the part type.
In previous releases, ExportAttribute was sealed.
It is now possible to subclass ExportAttribute, and this can be combined with the existing MetadataAttribute functionality.
This means that instead of:
It is possible to define a custom attribute that completely describes the export:
Thus users can declare both the exported contract and its metadata using only one attribute:
We expect this will be very useful for authors of extensible frameworks.
Note: We have also unsealed ImportAttribute, ImportManyAttribute and ImportingConstructor thus allowing these to be extended as well.
As an extensibility framework, it is important that MEF applications start and execute reliably even when some extensions lack required dependencies.
Stable Composition contributes to this goal by validating dependencies in advance.
In earlier releases, MEF would hand out lazy exports from parts with missing dependencies. Later, when the export was used an exception would be thrown because of problems creating the part.
There were two major issues with this:
The solution to this problem is:
Parts that have missing required dependencies are ‘rejected.’ They appear in the catalog, but the container never uses them.
MEF remains dynamic – as parts are added and removed from the composition, the state of part definitions can change. Parts that may have been rejected will become available when their dependencies can be satisfied.
The container now treats lazy references as promises. Once the container hands out a Lazy<T> export, the value is guaranteed to be available, and to remain available for the life of the part that imports it.
The parts available in a MEF container can change, either by adding or removing to the a ComposablePartCatalog, or directly via CompositionContainer.ComposeBatch().
In order to keep promises, changes like these are examined carefully and verified not to break anything already instantiated.
If such a change would cause an existing promise to be broken, the change is rejected by means of a CompositionException.
One of the implications of Stable Composition is that the rejected parts will simply never show up.
Because parts are interdependent, one broken part can cause a chain of other dependent parts to be rejected as well.
Finding the root cause of a ‘cascading rejection’ like this can be tricky.
Included in the samples under /Samples/CompositionDiagnostics is a prototype diagnostic library that can be used to track composition problems down.
The two basic functions that are implemented allow the rejection state of a part to be inspected, and the contents of an entire catalog to be dumped along with status and root cause analysis information.
For comprehensive diagnostics, the complete composition can be dumped in text format:
The output contains many interesting things, including ‘primary rejection’ guesses and analysis of common problems like mismatched type identity, mismatched creation policy, and missing required metadata:
There’s enough information here to correctly diagnose most common issues.
The dump technique above is comprehensive but verbose, and if you have access to the running process in a debugger, the following is more likely to be convenient:
The return value of CompositionInfo.GetPartDefinitionInfo() is an object that gives quick access to all of the same analytical information as the text dump, but relating to the part Foo. The API exposes:
The ExportProvider.GetExportsCore() method has gained a parameter to support Stable Composition. ExportProvider also has a new event ExportsChanging for the same purpose.
Simple ExportProviders that hand out the same values and do not recursively call into the container can ignore the parameter and event.
If you implement a custom ExportProvider that recursively calls into the container to satisfy dependencies of the exports it hands out, then you should participate in Stable Composition.
Likewise, if the set of available exports in an ExportProvider can change, you’ll need to fire the ExportsChanging and ExportsChanged events.
See the API documentation for these types for more details.
A number of other supporting API changes have been made, and a few obsolete or problematic items removed:
Enjoy the new release, and remember that the MEF discussion forum on CodePlex is a great place to get help if you find yourself stuck.
The MEF Team is very grateful to everyone who’s provided feedback and input into the new release. I hope we’ve hit the right note, but as always your comments are welcome.