Posterous theme by Cory Watilo

Filed under: MEF

MefContrib 1.0.0.0 sees the light of day!

Nearly one and a half years ago I joined the MefContrib as a contributor. Soon after I was given ownership of the projects by the guy that set it up, Bill Kratochvil. Back then MEF was still in its early preview bits and most of the stuff that existed in the MefContrib community were small sample applications on how to use MEF with ASP.NET and so on.

A lot has happened since. I am very happy to be able to announce the release of MefContrib 1.0.0.0, we tagged it a couple of days ago in our repository and you can download it from either our Github repository or at the download section of our website mefcontrib.com (we you also can get builds of the latest check-ins). A good resource for MefContrib related information is our twitter account @MefContrib, were we post news and you can also get information when new stuff is committed to the repository.

The Github page also contains a sample repository that currently host a couple of applications that shows to use the Convention Model, a way of using with with conventions instead of attributes, and the InterceptionCatalog, a catalog that uses strategies and interception hooks – this enables things like Aspect-Orientated Programming with MEF and it is the catalog that powers all other catalogs in MefContrib.

So what can MefContrib 1.0.0.0 add to your MEF toolbox?

  • InterceptionCatalog – This catalog lets your decorate another catalog and provide ways of adding new parts and exports at runtime, as well as to provide it with a set of interception hooks that you can use to modify parts. We ship with hooks for using DynamicProxy and LinFu together with MEF, which opens up for a completely new world of things you can do with MEF. Piotr Włodek has a very nice introduction post to the InterceptionCatalog that shows how you can use DynamicProxy to weave in new behavior at runtime.
  • ConventionCatalog – Removes the need to use attributes when defining parts, import and exports in MEF. You use a convention based approach to let MEF know how to compose the application. This offers some great powers with very little configuration. One interesting thing it also enables you to do, it so import and export things you do not have the source code for (for adding the attributes) or that was previously designed to work with MEF
  • FilteringCatalog – Enables you to use predicates to filter our discovered parts at runtime. For example, filter out parts that carries a specific piece of metadata or has a certain creation policy. Since it is based on a predicate you can write what ever filter you want
  • GenericCatalog – Provides open-generic support in MEF!
  • Unity integration – Provides a bridge between Unity and MEF, enabling both to work together to satisfy dependencies
  • FactoryExportProvider – A custom export provider that let you take charge of the instance creation in MEF. You can read more about the FactoryExportProvider at Piotr Włodek's blog

There are a lot more of small extensions and helpers included in the solution, so get the bits and try it out for your self. Oh, and all of the above also works great in Silverlight, using our Silverlight version of MefContrib!

If you have anything you would like to contribute to MefContrib please let us know! We are also looking for people to participate in other formats other than contributing features. Like most open-source projects, there are a lot things that needs more attention than we are able to give it at the pace that it deserves (not neglecting, just slow to get there).

So there you have it, a ton of MEF goodies for you to play with. We hope you like it and please let us know if you use the stuff in any products, would be awesome to know!

Media_httplh4ggphtcom_djfee

Microsoft Visual Studio 2010 Thank You Award

About two months ago I received an email from Doug Turnure, a program manager with the Visual Studio team at Microsoft, primarily focusing on customer feedback and adoption. He told me that Microsoft wanted to thank me for your contribution to the Visual Studio 2010 and .NET Framework 4 product releases, by sending me a small gift. I have been told that this is given out by nomination from team members and that this was for my continuous stream of feedback and crazy suggestions that I provided to the Managed Extensibility Framework during the course it grew from early previews to the RTM version that is now shipped.

A couple of days ago FedEx contacted me to inform me that they had a package they were trying to deliver. Apparently I had to be home between 10am and 4pm since that is when they do deliveries – something that might sound a bit trivial, but believe me it is not when you are on vacation, the sun is shining – and most of all – you have kids! It took a couple of days but they finally managed to make a delivery attempt when someone was home.

Here are some pictured of the contents of the package

Media_httplh5ggphtcom_smoin
Media_httplh4ggphtcom_gowic
Media_httplh4ggphtcom_ctfej
Media_httplh5ggphtcom_hexic
Media_httplh3ggphtcom_rbjci
 
Media_httplh3ggphtcom_diane

It is small box with a letter from S. Somasegar, Senior Vice President of the Developer Division at Microsoft, on the inside. In addition to that there is a class cube, with a side length of 6cm (about 2,36 inches) with text etched into different depths of the class. The Visual Studio 2010 logo and the .NET Framework logos are present, along with an inscription that says “Thank you for the lasting contribution you have made to Microsoft Visual Studio”.

All in all I think it is a pretty nice looking award and I feel honored that I was nominated, and accepted to receive it! Thank you Microsoft, both for the award but also for taking the time to listen to a single developers feedback during your development cycle of a new technology like the Managed Extensibility Framework. Especially thanks to Glenn Block whom was more than happy to interact with the community at every opportunity he got – both on and off business hours!

MefContrib has moved, bought new shoes and met new friends

There has been quite a lot going on behinds the scenes lately and I am finally able to share some of it with you! Existing stuff! New home, new shoes and new friends – what more does an open-source project really need? Read on to know what!

Our new home

For quite a while we have been talking about moving MefContrib for a couple of reasons. We have all been wanting to put some effort into learning Git more extensivly , so what better way than to move our entire repository from subversion to git? That is right, we have moved our repository from our Codeplex site to our new home at Github! Granted we are by no means Git experts, but we hope we will get there a bit sooner thanks to this, he he.

But one of the main reasons we wanted to move over to Github was because of the awesome tools they have in place to help out to work with community contributions. From the contributors perspective it is so incredibly easy to fork a repository, make some changes and then issue a pull request back to the main repository. Likewise, from the project owners perspective it is easy to keep track of forks and to merge contributions into the main repository.

And before you ask, yes we did talk about switching to Mercurial, especially after the native Mercurial support was rolled out on Codeplex. I work with Mercurial on nearly a daily basis at work and I love it, however we still felt that we wanted to take on the (albeit small) challenge of properly teaching ourselves Git and also take advantage of the awesome track record Github has of infusing community activity into open-source software.

If you do not have any prior Git experience yourself but still want to contribute, do not worry! We invite you along on our Git-learning journey and we will soon have the obligatory “This is how you work with our repository” information posted at our Github crib.

Our new shoes

The move to Github also marks another important change in the life of MefContrib. We have now completely upgraded the code to be compatible with .Net 4, Silverlight 4 and Visual Studio 2010! We are looking forward to being able to make use of all the new functionality that this brings to the table. A lot of people we have talked to about contributions have been building their stuff on the .Net 4 preview bits, so hopefully this means we will be able to get some of them into our repository in the future.

Further more we have decided to discontinue support for .Net 3.5, Silverlight 3 and Visual Studio 2008. We are going to make one final binary and source drop that targets the old platforms, but after that we will only be putting new features into the repository. This was not an easy decision to make but after taking a poll on what framework version people would be building MEF powered applications on, it stood clear that the vast majority would be targeting the newer version.

If there is demand for a .Net 3.5, Silverlight 3 and Visual Studio 2008 version and it is large enough, then we would probably reevaluate our decision. In the meantime the old version will still be available as a binary and source code drop, as well as the repository will be kept online. And as any open-source project would say; We accept patches!

Our new friends

If you have checked out our Github home by now (no? What are you waiting for?) you are likely to have spotted another change. We have added a couple of other repositories to our repertoire. We felt that we needed to keep a couple of things separate from each other so this is what we have got so far

  • MefContrib; Contains extensions to the Managed Extensibility Framework
  • MefContrib-Samples; Will contains sample applications on how to use MefContrib and possibly MEF
  • MefContrib-Tools; Here we will put tools that you can use with MEF, such as visualizers

We might be adding one or two more down the road, such as for our upcoming guides and docs, but do not worry, the distinction between all of them will be crystal clear!

Our future

… is in your hands, literally. We need your awesome contributions (we know they exist, the blogsphere is exploding with MEF contents right now!), we need your help to spread the word (social media for the win!), we need your feedback on what works, what does not working, what is missing and what is useless! In short, we need our community, just like any other open-source software. Are you with us?!

Bringing convention based registration to the Managed Extensibility Framework

If you have used the Managed Extensibility Framework before, you know that is uses attributes such as ImportAttribute, ImportManyAttribute or ExportAttribute as part of its discovery mechanism. This approach to configuration is know as the attributed programming model and it is a very easy to pick up and start using. As a believer of the convention over configuration software design pattern, adding configuration attributes on my domain objects, attributes which serves no other purpose than that of discoverability, is something I would like to avoid doing.

As a result of this, I decided to create a convention based programming model that could be used instead of, or side-by-side with, the attributed programming model. The result of this is a custom catalog which relies on conventions to define that parts without the use of attributes on your objects.

By using conventions you also get the ability to take any available type and have it participate in composition, something you would not be able to when using the attributed model since it requires you to have access to the source code, in order to add the attributes. This opens up for some pretty interesting scenarios because you are able to take types, that as not designed with MEF in mind, and have them take part in composition.

If you want to try out the convention based programming model yourself, you can head over to the MEF Contrib website. At the time of this writing, the latest binary release of MEF Contrib is 0.9.0.0, which does not include the convention based programming model, so you will have to grab the latest version of the source code from the repository. It will definitely be in the next binary release though.

Before we get into the details of what the convention based programming model is, let me start with telling a bit about it it (currently is not). This release does not signal a final product, it should be considered more like a technology preview. The code has been put through quite a lot of testing, but chances are that there are still some bugs (if you find any, then please let me know so that I can resolve them) that have not been caught yet. It is also likely that there will be breaking changes in later releases, but I will do my best to avoid or minimize them.

The are a couple of limitations in the current implementation, such as not supporting constructor imports and not being able to compose existing instances of a type. However, I am aware of these short coming and they are all planned to be resolved in following releases. At the end of this post I will mention a couple of things on how you can help shape the future releases of the convention based programming model, but for now let us take a closer look on what makes it tick.

Convention Primitives

There are three interfaces in the model that defines the type of conventions that can be created; IPartConvention, IImportConvention and IExportConvention. All of the convention interfaces follow the same design. The conventions use a predicate to identify the things that they should be applied to, as well as a series of properties that define things such as contract name, type identity, creation policy, and metadata that will be applied to the created parts.

For each of the interfaces there is a default implementation. These implementations are, not surprisingly, called; PartConvention, ImportConvention and ExportConvention. Instances of these types are used to define the conventions that should be used by MEF. You can provide additional functionality by inheriting the convention types or provide your own by implementing the convention interfaces yourself.

Being able to create conventions with custom functionality is a very powerful feature in the convention based programming model and the rest of the model have been designed with this in mind by exposing extensibility points that will make it very easy to make their use as transparent as possible. So if you ever find yourself in a place where you are missing some functionality, just add it!

Convention Registries

Manually creating instances of the convention types can be tedious work, but thankfully there is a thing called convention registries that help provide a better experience. The registries are implementations of the Object Scoping pattern and provide a Domain-specific language (or DSL for short) for defining conventions. This pattern is used by popular frameworks, such as NHibernate and StructureMap.

The registries takes advantage of powerful language features such as nested closures, lambda expressions and extension methods to provide a richer setup experience then what you get when manually creating convention instances.

Below is a sample registry that is used to define two parts. The first part exports the ApplicationHost type as a singleton and also defines that the Extensions property of that type should be treated as an import with the contract name and type of IApplicationExtension. The second part exports all types that implement the IApplicationExtension interface, using the same contract name and type as that used for the Extensions property on the ApplicationHost type.

public class ExtensionRegistry : PartRegistry{    public ExtensionRegistry()    {        Part()            .ForTypesMatching(x => x.Equals(typeof(ApplicationHost)))            .MakeShared()            .Exports(x => x.Export().Members(m => new[] { m }))            .Imports(x =>             {                x.Import()                    .Members(m => new[] { m.GetProperty("Extensions") })                    .ContractName<IApplicationExtension>()                    .ContractType<IApplicationExtension>();            });        Part()            .ForTypesMatching(x => x.GetInterfaces().Contains(typeof(IApplicationExtension)))            .Exports(x =>             {                x.Export()                    .Members(m => new[] { m })                    .ContractName<IApplicationExtension>()                    .ContractType<IApplicationExtension>();            });                 }}

Do not worry if you think this looks complicated and verbose, you are right but fortunately what you are seeing is the raw registry DSL and there are several ways in which this could be made a lot simpler. Later in the post I will go into a bit more detail on how you can customize the registry DSL, but until then know that you are not stuck with the above code. The entire convention based programming model have been designed with extensibility in mind.

Type loader

Earlier I mentioned that all of the convention types used a predicate to determine that they can be applied to. For part conventions the predicate is on the Type type, meaning it examines an entire type to determine if the convention could be applied to it to create a MEF part. Depending on the predicate you could end up matching a single type or every single type available in the application domain.

But what if you wanted to make sure that the conventions could only be applied to a specific subset of all the available types?  This is where type loaders can help you out. A type loader is used to define the subset of types that you want your conventions to have access to. Not that this does not mean that the conventions will be applied on each of those types only which types that the predicate is evaluated against.

The functionality of a type loader is defined by the ITypeLoader interface, which consists of two methods; AddTypes and GetTypes. When adding types to the type loader, you pass in a Func<Type[]> function, which will then be evaluated when MEF asks the convention based programming model for the parts it can provide. This basically means that you get deferred evaluation of which types that are available, giving you the ability to make a runtime decision.

There is a default implementation of the ITypeLoader interface called TypeLoader that should be enough for most needs, but just as with the convention primitives you could just as well create your own implementation if you need custom functionality. The convention based programming model will have no trouble consuming custom implementations.

The following example shows how a type loader could be used to restrict the available types to the types of the current executing assembly.

var loader =     new TypeLoader();loader.AddTypes(() => Assembly.GetExecutingAssembly().GetExportedTypes());

Later versions will include a configuration API for the type loader, that will look something like this

var loader =     new TypeLoader();loader.Configure(x =>{    x.AddExecutingAssembly();    x.AddAssembly(@"SomeAssembly.dll");});

You will be able to write extension methods, for the configuration closure, to provide additional ways to add types to the type loader. The last thing to say about the type loader is that they are used on a catalog level and not on a registry level. This means that all the conventions, used by the catalog, will be restricted to the types that the type loader instance, passed into the catalog, makes available.

ConventionCatalog

There really is not much to say about the catalog used by the convention based programming model. You use is just as any other MEF catalog, the difference comes in the parameters that you provide when creating an instance of it. That catalog is called ConventionCatalog and it has two constructor two overloads; one that accepts a collection of part conventions along with a type loader and the second one that accepts in a collection of part registries along with a type loader.

The purpose of the catalog is to take the available conventions and turn them into ComposablePartDefinitions, a sort of schema of the part and its imports and exports, that is used by the container to figure out how all things are connected with each other. The container queries the catalog of all the part definitions that it can provide.

ConventionPart

One of the core types in MEF is the ComposablePart type. It is one of the main actors in the composition mechanism and is responsible for satisfying the imports on instance that it represents, which includes stuff like casting a collection export definitions into the correct type of the importing member. The latter sounds like a simple cast when you first look at it but there is more to it than meets the eye. Taking an arbitrary collection of values and converting them into something that can be assigned to an importing member requires quite a bit of plumping. Notice that I specifically used the term convert and not cast, this is because sometimes it involves dynamically creating an instance of specific collection type, casting all values into a type that the collection can store and then populate it.

The ComposablePart is also the type that allows existing instances to be composed, unfortunately the implementation used internally by MEF is marked as Internal along with the supporting infrastructure code to that makes it tick. It is also built around the concept that the instance, you want to compose, carries (remember the standard way for defining imports and exports are by using attributes) the information required to create a ComposablePartDefinition.

This means that if you want to perform composition on types that does not carry the information on itself (such as in the case where the conventions are defined separate to the types), you will have to implement a custom ComposablePart and that requires quite a bit of work. It can be done, I have done it once before for the provider based programming model, however the current version of the convention based programming model does not have a custom ComposablePart implementation.

To overcome this in the first preview of the convention based programming model, a “buddy”-part was introduced to bridge the gap between the two models. The ConventionPart<T> type is an attributed type used to perform composition using conventions. The type is built in such a way that it has a public property called Imports which is a collection of the type T and has been decorated with the ImportMany attribute. The type of the generic parameter T is the type you want to compose using the conventions.

Passing this into the container will have it satisfy the Imports property and all related imports on exports, in this case those that are defined on the type T, using all the available ComposablePartDefinitions. The type we are really interested in is T so once the composition has taken place we can get one or more composed instances of T from the Imports property.

To use it, create a new instance the type you want composed and pass it into the container, just as any other instance.

var part =    new ConventionPart<ApplicationHost>(); var container =    new CompositionContainer(catalog); var batch =    new CompositionBatch();batch.AddPart(part); container.Compose(batch); var composedInstance =    part.Imports.First();

Default conventions and community feedback

I mentioned earlier that the registry DSL is a bit verbose and that there are several ways in which it could be a lot simpler. The main reason for it being so verbose and raw is that it provided a nearly one-to-one mapping against the convention primitives a long with some additional overloads.

There is also another thing to consider and that is default conventions. What conventions could be included to represent default conventions? Your idea of default conventions are probably not the same as the next guys. It is not a trivial task to identify a set of conventions that can be reused across multiple projects by different people and companies.

I am not saying that it is impossible to identify some common conventions that can be packed up and shipped with a later release, in fact I am sure there are. This is where I will turn to the community and ask for you to help try to identify things that could be turned into reusable items, such as conventions and extensions.

Speaking of extensions, the entire registry DSL is built to support of rich extensibility model though the help of extension methods. I am certain that there are lots of useful extensions that could be written for it and I would very much like to hear back from you with ideas and if you can provide the implementation yourself then that would be even better. I will make sure to include contributions that could be useful for others to have.

For example with a bit of extension method magic, the following line

.ForTypesMatching(x => x.GetInterfaces().Contains(typeof(ILogger)))

could be transformed into

.ForTypesMatching(x => x.Implements<ILogger>());

here an extension method has been added to the type class, to return a boolean value based on if the type implements the provided interface or not. This is an extension method to help define a predicate, but there is nothing stopping you from continuing up one level and apply an extension method to the DSL itself. So for example you could remove the entire ForTypesMatching predicate method with a custom one

.ForTypesImplementing<ILogger>()

this is a much more readable approach. I could see a scenario where you would like to add multiple custom predicate calls in your part convention declaration and I might change the predicate parameter into a collection of predicates in a later release. Let me know if this is something that would be useful to you!

Another example of how the same clean-up can be made for import/export predicates such as

.Members(m => m.GetProperties().Where(p => p.ReturnType.Equals(typeof(ILogger))))

that identifies all properties that returns an ILogger instance, could be turned into

.Members(m => m.PropertiesOfType<ILogger>())

or again, move the extension method into the registry DSL itself and you end up with

.PropertiesOfType<ILogger>()

I definitely plan on including these kind of extensions in later releases and with your help that could turn out to be a sooner than later event! Just to give you an example of what the previous registry DSL sample could look like, if you applied some extension method magic to it, have a look below

public class ExtensionRegistry : PartRegistry{    public ExtensionRegistry()    {        Part()            .ForType<ApplicationHost>()            .ExportType();            .MakeShared()            .ImportProperty<ApplicationHost>(x => x.Extensions);        Part()            .ForTypesImplementing<IApplicationExtension>()            .ExportTypeWithContract<IApplicationExtension>();    }}

What is next

Like I mentioned, there are a couple of known limitations, such as no support for constructor imports and not being able to compose instances with the help of the conventions. Other than that, I would really like to let community feedback drive the roadmap of this project. That said, I would love to hear everything about your experience and issue from using the convention based programming model, so drop me a line!

Furthermore, if you create any useful registry DSL extension method or default convention implementations – please consider sharing them with the community. Send me a line and I will see about getting them into the source code. Even if you only have ideas on extensions, but lack the time or skills to create them, contact me anyway and I will see about creating an implementation as soon as I have the time.

Over the next couple of weeks I am going to try to start a small blog series about the convention based programming model and highlight certain things in each of the posts. So keep an eye out, download the source code and start playing with the bits, blog about your experience and let me know.

De-mystifying Meta-data in the Managed Extensibility Framework

One of the features in the Managed Extensibility Framework is the ability to associate metadata with the imports, exports and even the part that carries them. Metadata is commonly referred to as “data about data” and in the case of MEF it enables you to make run-time decision on the things that have been dynamically discovered by the container.

Not only does the metadata support in MEF enable you to make run-time decisions, but it also enables you to set up constrains on imports by telling the container what metadata that exports has to satisfy in order to be accepted. Metadata import constraints does not only enable you to reject exports with incomplete metadata, but it also enables you to do things like partitioning your exports based on available metadata.

The single most important thing to be aware of with regards to the MEF metadata support is that, internally, all metadata is stored in a Dictionary<string, object> structure. Using such a trivial implementation internally, MEF opens up for some pretty interesting things to be done with metadata.

So let’s see what sort of things that can be done.

Adding metadata to exports

The easiest way to add metadata to an export is to decorate it with the ExportMetadata attribute. The attribute can be applied to all type of exports (types, fields, properties and methods) and takes two parameters; a string key and an object value. The attribute can be applied multiple times to add more than one piece of metadata to the export.

[ExportMetadata("AuthenticatedUsersOnly", false)] [ExportMetadata("Priority", Priority.Low)] [Export(typeof(IExtension))] public class DefaultExtension : IExtension {     public DefaultExtension()     {     } }

The DefaultExtension export has two pieces of metadata associated with it; a boolean that indicates whether or not it should be available only to authenticated users or not, and an enum value indicating the priority of the extension. None of these are MEF specific and have been created for the demonstrative purpose of this blog post. You can add any key/value pair that you like, but they have to conform to the normal rules of values in attributes.

Accessing metadata on imports

To be able to tap into the available metadata for imported values, you have to let the MEF container know that you are interested in using it. There is a snag here though. You can only access import metadata if you have lazy imports. The reason for this is quite obvious if you stop to think about it for a moment. If you were to directly import instances, then how would you get the additional information passed to you? You need a container that can contain both a way to get to the actual instance and also the metadata that is associated with it.

So in order to get access to import metadata you could modify an import looking like the one below

[Import(typeof(IExtension))] public IExtension Extension { get; set; }

into the following one

[Import(typeof(IExtension))] public Lazy<IExtension, Dictionary<string, object>> Extension { get; set; }

Remember how I said that metadata is really just a dictionary with string keys and object values? Here we are telling MEF that we would like to get access to that dictionary for the import in question. The Lazy<T, K> type is a special version of Lazy<T> class created by the MEF team and it contains a property called Metadata, which has the property type defined by the type parameter K, so in this case it will be of the type Dictionary<string, object>>.

A call to

this.Extension.Metadata

will give you access to the normal members of any Dictionary<string, object> instance. Armed with this, you are now ready to make run-time decisions on the imported values! Simple, is it not? And there is more to come!

Moving from a weakly-typed to a strongly-typed reading experience

The biggest weakness so far is the fact that we are accessing metadata on a weakly-typed dictionary. Not only do we have to make sure that a certain piece of metadata is available before we use it, or risk throwing an exception, but we also have to perform explicit casts because all values are stored as objects.

As if the two drawbacks mentioned above were not enough, there is a third drawback to the approach. By accessing metadata using string keys we are introducing magic strings, a horrible code smell that is going to make maintenance of the codebase awful in the long run and it is not very refactor-friendly either!

Luckily MEF has the ability to overcome all these things using a very simple concept; metadata contracts. A metadata contract is nothing more than an interface with read-only properties. How does this improve the way you work with metadata? Each read-only property in the metadata contract is strongly-typed and the name of the property is the name of the metadata item!

Internally MEF will still represent metadata using a Dictionary<string, object> instance. However, because the framework uses structural typing it can inspect the metadata contract and determine if the contents of the dictionary satisfies it.

So let us create a metadata contract for the metadata that was added to the DefaultExtension earlier.

public interface IExtensionMetadata {     bool AuthenticatedUsersOnly { get; }     Priority Priority { get; } }

Yes, it is that simple! The next thing to do is to modify the import so that it lets MEF know that instead of getting back the raw metadata dictionary, we want to get back a metadata view that matches the metadata contract

[Import(typeof(IExtension))] public Lazy<IExtension, IExtensionMetadata> Extension { get; set; }

Now if you call

this.Extension.Metadata

you will gain access to two, strongly, typed properties; AuthenticatedUsersOnly and Priority, the same two properties that was defined on the IExtensionMetadata interface. This greatly simplifies the consumption of the metadata since there no longer is a need to verify that the metadata key is available or to cast the values before you use them! We have also gotten rid of the magic strings and if either of these properties are renamed you will get a compiler error if the name is not updated everywhere it is accessed!

Defining metadata requirements on imports

You may or may not have realized it yet but we have done all the work that is needed to setup metadata requirements on imports. Using the metadata contract, MEF will reject all exports that do not contain all the metadata that is needed to satisfy the metadata contract.

Say you wanted to make the AuthenticatedUsersOnly metadata optional. This would not be a problem if you accessed metadata using the dictionary; the key/value pair would simply be missing. However with metadata contracts the entire export is rejected, so how can we get around this and implement optional metadata requirements?

Simple, we use the DefaultValue attribute. With this attribute we can tell MEF what default value to use in replacement for a missing item in the dictionary. So all properties that have been decorated with this attribute are considered optional, and all others are mandatory.

Moving from a weakly-typed to a strongly-typed writing experience

Up until this point all metadata that has been added to the DefaultExtension part have been done so using the ExportAttribute. It exhibits all the problems we had while consuming the weakly typed, magic string based, dictionary of metadata; it is weakly-typed (object values) and relays on magic string (metadata name strings).

So, how can we get the same strongly-typed, no magic string, based functionality when defining metadata? The answer to this is a custom metadata attribute. Luckily MEF provides the functionality to define your own metadata attributes, which enables you to get rid of the ExportMetadata attributes and the issues that comes with it.

To create a custom metadata attribute, you do just like you would do when creating a normal custom attribute you also decorate it with the MetadataAttribute (I know! Metadata for metadata. Enough to blow your mind!). The properties on the custom attribute will be used by MEF to populate the internal metadata dictionary, again with the property name as the dictionary key and the property value was the dictionary value. The difference with a metadata contract is that the properties can be read-write.

[MetadataAttribute] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Module, AllowMultiple = false)] public class ExtensionMetadata : Attribute {     public ExtensionMetadata(bool authenticatedUsersOnly, Priority priority)     {         this.AuthenticatedUsersOnly = authenticatedUsersOnly;         this.Priority = priority;     }     public bool AuthenticatedUsersOnly { get; set; }     public Priority Priority { get; private set; } }

There are a couple of key things to pay attention to.

  • The attribute has been decorated with the MetadataAttribute; without it MEF will ignore it and no metadata will be added to the export
  • The attribute usage is setup to be valid on all things that can be exported: types, fields, properties and methods
  • The AllowMultiple value is set to false (more on this below)

Setting AllowMultiple to false is very important. Without it, MEF accepts that you add the attribute more than once on the same export. If you think about that for a moment you should realize that this means that the same metadata key could potentially contain more than one value. Makes sense, yeah? MEF handles this by storing arrays of values instead of single values in the dictionary, meaning the way you access is will be different. There are usages for this behavior but for the most part you only want a single value, so remember to set this to false unless you explicitly know what you are doing.

Putting this new attribute to use, the DefaultExtension will be defined as follows

[ExtensionMetadata(false, Priority.Low)] [Export(typeof(IExtension))] public class DefaultExtension : IExtension {     public DefaultExtension()     {     } }

Much nicer is it not? Strongly-typed and no magic strings. Not only that but by naming the attribute ExtensionMetadata we have setup an expectation on the developer using the attribute for what metadata we require to be supplied. Using the ExportAttribute there is no way to communicate this to the exporter other than sticking it in the documentation and hoping it will be read.

Conveying optional and mandatory metadata with custom attributes

Remember how we were able to decorate properties on the metadata contract to create optional metadata requirements on imports? The same thing can be done with the values on the custom metadata attributes. We can achieve this by removing the constructor parameter for the AuthenticatedUsersOnly property, setting the default value in the constructor body and making the property read-write.

[MetadataAttribute] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Module, AllowMultiple = false)] public class ExtensionMetadata : Attribute {     public ExtensionMetadata(Priority priority)     {         this.AuthenticatedUsersOnly  = false;         this.Priority = priority;     }     public bool AuthenticatedUsersOnly { get; private set; }     public Priority Priority { get; private set; } }

Using the attribute and relying on the default value for the AuthenticatedUsersOnly property would look like this

[ExtensionMetadata(Priority.Low)] [Export(typeof(IExtension))] public class DefaultExtension : IExtension {     public DefaultExtension()     {     } }

If you instead wanted to provide a value for the property you would simply do:

[ExtensionMetadata(Priority.Low, AuthenticatedUsersOnly  = true)] [Export(typeof(IExtension))] public class DefaultExtension : IExtension {     public DefaultExtension()     {     } }

Starting to get the idea of just how much more enjoyable the custom metadata attributes are to work with than the ExportMedata attribute?

A side note on the structural typing of metadata

Because of the usage of structural typing inside of MEF, you can combine custom metadata attributes with ExportAttribute. For example the following example sets the priority using the custom attribute and then adds the metadata information (about only being valid for authenticated users) using the ExportAttribute.

[ExtensionMetadata(Priority.Low)] [ExportMetadata("AuthenticatedUsersOnly", true)] [Export(typeof(IExtension))] public class DefaultExtension : IExtension {     public DefaultExtension()     {     } }

MEF will take all metadata and put it in the same dictionary before it uses structural typing and determines that it can satisfy the metadata requirements imposed on the import by the IExtensionMetadata metadata contract.

[Import(typeof(IExtension))] public Lazy<IExtension, IExtensionMetadata> Extension { get; set; }

Neat, ey?

Combining custom metadata attributes with metadata contracts

Right now we are at risk of getting the required import metadata (defined by the IExtensionMetadata metadata contract) and the expected exported metadata (defined by the ExtensionMetadata attribute) out of sync with each other. How? What happens if a property is added on either one of them and we forget to add the corresponding property on the other one? Bad things could happen. We do not want bad things to happen so let us resolve (or at least minimize) this potential problem.

Since the ExtensionMetadata attribute is a regular class, we can have it implement the IExtensionMetadata interface! So if you alter the definition of the interface you are going to have to reflect the changes (at least for when you add new properties) on the attribute or you will get a compiler warning.

[MetadataAttribute] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Module, AllowMultiple = false)] public class ExtensionMetadata : Attribute, IExtensionMetadata {      public ExtensionMetadata(Priority priority)     {         this.AuthenticatedUsersOnly  = false;         this.Priority = priority;     }     public bool AuthenticatedUsersOnly { get; set; }     public Priority Priority { get; private set; } }

A minor change that improved the overall design.

A side note on the metadata dictionary

If you have an import that retrieves metadata using the dictionary you may notice that there are some additional metadata items in there already. For exports MEF ,will add information about type identity - a sort of namespace for contract names - and for parts it will add metadata about the creation policy. Do not worry about these; they are required by MEF to function and they will not have any impact on your metadata contracts, thanks to structural typing.

That is all there is to it

That is all I have to say about MEF metadata for now. Being able to add metadata support in your application is a powerful thing and as you could see there is nothing difficult about it. With a bit of customization you can provide a much better metadata experience in your code and for the exporters, than using the default ExportAttribute and Dictionary<string, object> container.

Using a custom export provider to serve images as exports

The Managed Extensibility Framework enables you to export types, fields, property or methods by applying the ExportAttribute on the things you want to export. A discovery mechanism, known was catalogs, are then used to identify the attributed parts so that the container can satisfy the required imports.

This very simple approach to composition is one of the strong points in MEF, but something you need more. Imagine you wanted to export something that was not associated with a type you were able to add an attribute to (perhaps you do not control the source code), something a bit more complex like a piece of XAML code or an image.

To enable scenarios like these, the MEF team made a huge refactoring of their code, in time for the Preview 6 release, and introduced the concept of export providers. In short, an export provider enables you to associate a contract with an object instance and return it as an export that the container recognizes.

I won't go into details on how export providers work in the MEF container, for that you should read Glenn Blocks post on Using ExportProvider to customize container behavior Part I.

However, to show how a custom export provider can be used make complex types available to take part in composition, we are going to build a small application that imports images from the local file-system.

An image is not something that you can just add an export attribute to since you do not control the source code of the image class. Even if you did have access to the source code, adding the attribute would mean that all instances would be discovered by MEF, instead of the image set you do want to use.

The image gallery application

The application I am going to build is a simple WPF image gallery application that will display the available images as thumbnails, with an added drop shadow (just because I thought it was cool to discover how easy the effect was to add and because it does make it look less boring that it actually is).

Media_httplh4ggphtcom_hascx

The entire application is built from the following piece of XAML code.

<Window x:Class="Gallery.Window1"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     Title="Image Gallery" Height="274" Width="491">     <Grid>         <WrapPanel Name="Gallery">             <WrapPanel.BitmapEffect>                 <DropShadowBitmapEffect />             </WrapPanel.BitmapEffect>         </WrapPanel>     </Grid> </Window>

A word of caution for the WPF gurus out there. I am no WPF developer so please do not pay too much attention on either the design or implementation of the WPF shell. I’m sure there are a lot of things that could be done to improve both, but lucky for me this is a MEF blog post!

As far as the UI is concerned, the images originates from an observable collection of images (that is, System.Window.Controls.Image instances and not System.Drawing.Image instances), it knows nothing about the fact that the images will be loaded from the local file-system.

[ImportMany(typeof(IGalleryImage))] public ObservableCollection<Image> Images { get; set; }

Note, the IGalleryImage interface is just an empty interface used to create a strongly-typed contract between the import and the custom export provider that will be used to provide the image instances.

There are more to exports than meets the eye

An export is more than a concept in MEF, it is also a type. To be more specific, the export type enables you to inform MEF that you can provide a value for an import of a specified contract. What this means is that when MEF tries to find exports to satisfy an import, you have the ability to hand out instances of what ever you want, a long with metadata if you wish to.

To create a custom export provider all you need to do is inherit from the ExportProvider base class, found in the System.ComponentModel.Composition.Hosting namespace. Once inherited, the export provider requires you to implement a single member; the GetExportsCore method.

The signature of the GetExportsCore method is very simple

IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)

It takes two parameters; an import definition that contains information about the import that MEF is trying to find suitable exports for, and an object which can be used to take part in an atomic change of the container (we are going to ignore the second parameter in this post). The method is expected to return an IEnumerable of Export instances that the export provider was able to match to the import definition.

So let us have a look at the image export provider

public class ImageExportProvider : ExportProvider {     public ImageExportProvider(string path, Type contractType)         : this(path, AttributedModelServices.GetContractName(contractType))     {     }     public ImageExportProvider(string path, string contractName)     {         this.Path = path;         this.ContractName = contractName;     }     public string Path { get; private set; }     public string ContractName { get; private set; }     protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)     {         return !definition.ContractName.Equals(this.ContractName) ?             Enumerable.Empty<Export>() :             this.GetImageExports();     } }

I have omitted the implementation of the GetImageExports method for now, so that we can focus on the core. The two constructors of the export provider enables you to tell it where it should look for the images on your local file-system and also what contract it should respond to (either by sending in a string or a type). The GetExportsCore method checks if the requested contract can be satisfies by the contract that the export provider is configured to serve exports for. If the contracts does not match, an empty result set is returned; otherwise it builds the exports from the images found at the specified path.

The image exports are built by the GetImageExports method

private IEnumerable<Export> GetImageExports() {     var fileNames =         Directory.GetFiles(this.Path, "*.jpg");     var exports =         from fileName in fileNames         select new Export(this.ContractName, () => CreateImage(fileName));     return exports; }

Note. Only jpg images will be loaded by the GetImageExport method. This is because the GetFiles method does not enable you to pass in multiple search patterns and for the sake of clarity I decided not to add the logic for make multiple calls, each with a different filter. There are multiple ways to solve this, Mikael Svenson (known as @mikaelsvenson on twitter) was inspired by my little twitter rant about this short coming and decided to implement a nice extension method to solve the problem. You can find his solution on his blog.

The method simply gets the name of all the images in the specified path and creates a new export instance for each of them. Notice the parameters of the export instance. The first parameter is the contract that the export can satisfy and the second parameter is a lambda function that will be executed as soon as MEF asks the export for the value. In this case the lambda will call the CreateImage method to create the actual Image instance from the file name.

Note. There is a second constructor overload for the Export type. The second overload accepts an IDictionairy<string, object> instance, which the data structure used by MEF to represent metadata. So the export provider could be extended to return metadata about the image as well, for example the image dimensions or perhaps the color depth.

For the sake of completeness, here is the full implementation of the CreateImage method

private static Image CreateImage(string fileName) {     var source =         new BitmapImage();     source.BeginInit();     source.UriSource = new Uri(fileName);     source.DecodePixelWidth = 200;     source.EndInit();     var image =         new Image         {             Source = source,             Width = 100,             Height = 100,             Margin = new Thickness(5)         };     return image; }

Again this is WPF magic, something I am not used to writing so there are probably better ways to do the above. I am all for learning the proper techniques, so if there is a better implementation for the CreateImage method, please drop a comment at the end of the post and I will update the post with the improved implementation!

Wiring up the container

Now we have the host application and we have the custom export provider that knows how to load images from the local file-system and serve them up as MEF exports for a specified contract. The next thing we need to do it to let MEF know about the export provider so that it can query it for matching exports, when it tries to satisfy imports on a part that is being composed. In order to do this, all we need to do is to pass in an instance of the export provider into the constructor of the container instance.

private void Compose(){    var imageFolderPath =        Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);    var imageProvider =        new ImageExportProvider(imageFolderPath, typeof(IGalleryImage));    var batch =        new CompositionBatch();    batch.AddPart(this);    var container =        new CompositionContainer(imageProvider);    container.Compose(batch);}

The compose method is where the application wires up the MEF integration. Notice how an instance of the ImageExportProvider is created and the path to an image folder, and the contract type IGalleryImage (same as was used on the collection import) is passed in. The export provider is then passed in as a constructor parameter when the container is created. No catalog is used in this sample, meaning that the export provider is the only source of exports. However, there are constructor overloads which enables both catalogs and export providers to be passed in.

In conclusion

Using a custom export provider you get the ability to extend the functionality of your composition in a very simple way. In this sample I showed how you could load images from the local file-system but there is nothing preventing you from retrieving the images from other sources, perhaps from flickr, picasa or even from multiple sources at once!

I hope this gives you some idea of how export providers can be used to create a richer MEF story in your application. Images is just one possbility for export providers, but by just taking a moment to think about it I’m sure you can think of a lot more places where they can be handy.

The full source code can be downloaded from my codeplex.com page

An introduction to MEF programming models

Disclaimer: This is a prototype and work in progress. While the code does work it has not gone through the same degree of testing as the Attributed Programming Model that is shipped with the Managed Extensibility Framework


Back in late November 2008, when MEF Preview 3 shipped, I started looking into what the Managed Extensibility Framework was and what it had to offer. After having spent a couple of weeks exploring the shipped features of the framework, I soon started looking for ways that I could extend it with custom functionality.


One of the ideas I had was to write a custom catalog and instead of extracting part information from the types in an assembly, I wanted to use the configuration file to define parts. This would get rid of static part definitions using the Import/Export attributes and instead introduce a way of modifying the composition of an application even after it had been built and shipped.


After spending some time digging around in the framework it soon dawned on me that this would be impossible, because of the dependency it had on extracting definitions from types in assemblies (remember this was back in Preview 3, a lot has changed in the framework since).


I spent some time talking to Glenn Block, Program Manager of MEF, and it soon dawned on me that the framework was built around the concept of programming models. This definitely opened up a completely different realm of possibilities with the framework and also turned my project from a two day coding session into an open source project.

Programming models

I would go as far as to say that programming models are the least known feature of the entire framework, but if you ask me it is one of the most interesting ones. The MEF team designed to allow the framework itself to be extensible so you could customize it to work the way you need.


To get a better understanding of programming models, and how they relate to MEF, it is easiest to think of MEF as a two tier architecture.

 

Media_httplh4ggphtcom_vjjhp

 

The core services tier provides all the necessary functionality to perform part composition. The main responsibility of this tier is to figure out which export goes to what import. There are a bunch of other things that is taken care of in this tier such as lifetime management and part creation policies.


However, the core services does not implement the logic of how the compositions are made, not how the exports and imports are defined. This is the responsibility of the programming model tier. Flexibility in this tier allows customization of composition behavior and capabilities. For example Microsoft is shipping a single programming model in the initial release of the framework.


The model is known as the Attributed Programming Model and it has gotten its name from the fact that is uses attributes to provide a declarative approach for defining parts. To give you an idea of some of the behavior and capabilities that the attributes programming model adds to MEF, please review the following list

  • Part definitions - Allows imports and exports to be defined using a declarative approach with the help of attributes
  • Recomposition control – Control if an import can be satisfied more than once, for example if new matching exports are identified by the framework
  • Default value behavior – Control if it’s ok for an import to not be satisfies, i.e. is no matching exports is found then the default value of the import type will be kept instead of throwing an exception
  • Interface exports – Define that an interface can be used to create parts. All classes that implement the interface can then be turned into exports
  • Export inheritance – Ensure that exports which have been inherited from a base class also will be satisfied
  • Import type support – Enables you to import different types of imports, such as single imports, collections and arrays
  • Hierarchical composition – Enables nested relationships of imports and exports

This is far from a complete list of what the attributed programming model adds to MEF, but it gives you an idea of just how important programming models are to the framework. Imagine removing the model. Imagine what would be left.


As you can see if you remove the programming model from the framework stack then there’s very little functionality left. So with this knowledge you might think that creating a custom programming model would require a lot of work. It's quite possible that you are right, it all depends on the functionality you wanted to put into your model.

Creating a custom programming model

Creating a custom programming model varies in complexity, depending on the behavior and functionality you want to include. Either way you need to know a bit about some of the classes that exists in the framework and that are used to customize it.


These classes are collectively known as the Composition Primitives

  • ComposablePartDefinition – A high level description and factory of parts that can be involved in the composition of an application
  • ExportDefinition - Describes a capability that a part has to share in the composition
  • ImportDefinition – Describes a compositional dependency that a part has. This is a requirement that a part needs to have satisfied when it participates in composition
  • ComposablePart - Provides a high-level abstraction of the underlying instance of a part. Contains the logic for both satisfying the requirements of a part and serving the instance once requested
  • ComposablePartCatalog - Provides the mechanism for discovering and supplying part definitions to the framework

Depending on the complexity of the programming model you are implementing, you are going to be implementing one of more of these classes. You can read more about the Composition Primitives in the Hosting the .NET Composition Primitives by Nicholas Blumhardt, member of the MEF team.


There is also the option to build a composite programming model, i.e. a model which leverages the functionality of an existing programming model to provide new functionality. An example of such a model is the Functional Programming Model prototype by Glenn Block. You can read more about it in the Creating a functional programming model for MEF post on Glenn’s blog.


Next we're going to looking at a custom programming model that I have been working on for a while now. It's part of the MEF Contrib project and the full source code is available for download.

The provider model

The provider model is a custom programming model for MEF, built from the bottom up to support a rich extensibility experience. The idea for the model is to try and be as feature equivalent as the Attributed Programming Model but to add custom functionality on top of that. The model is in a very early development phase and even though the model works, it has not gone through the same amount of testing as the model that is being shipped with MEF. So if you plan on using this model in production code, then please perform an adequate amount of testing first. If you do find any issues please let me know, or even better contribute a patch!


The provider model is only possible because the people on the MEF team decided that there should be as loose coupling between the core functionality of the framework and extended behaviors and capabilities. In my opinion this is one of the most important design decisions they have made and it enables you to customize the MEF stack to exactly match your needs.


This is going to be  a brief overview of the provider model and its functionality. For a more in-depth documentation please refer to the documentation over at the MEF Contrib webpage. Please drop a line in the discussion forum is you have any thoughts on the model, suggestions on enhancements or end up using it in a project – I’d really like to know if you use it in an application!


Definition Providers

This was the very first feature that made it into the provider model. Initially I was only going to use the configuration file to define parts but when Glenn and I bounced some ideas back and forth I soon realized that it wouldn’t be too much work to build an open-ended approach for supplying part definitions to the model. The Attributed Program Model is limited to using attributes to declare parts, but the provider model adds a third tier on the MEF stack – the definition providers tier.

 

Media_httplh3ggphtcom_jxmoa

 

The definition provider tier is an abstraction layer between the model and the way that definitions are provided. The new tier introduces an interface called IDefinitionProvider and all you need to do in order to talk to the provider model is to implement a single read-only property, called Parts, that the interface defines and you are ready to go. Of course you also need to implement the logic for defining the definitions.


At the time of this blog post there are three definition providers included with the model

  • XML – Defines definitions with the help of the app.config file
  • Fluent – Uses a fluent API to define parts with the help of code
  • Attribute – A provider model compatible way of defining parts with attributes

You tell the model which definition provider to use by providing the type to the catalog used by the model. The name of the new catalog is DefinitionProviderPartCatalog and below is an example of how you would setup the model to use the app.config way of defining parts. First you need to define the parts in the configuration file.

<mef.configuration>  <parts>    <part type="MefContrib.NullMessageService, MefContrib" >      <exports>        <export contract="IMessageService" />      </exports>    </part>    <part type="MefContrib.Program, MefContrib">      <imports>        <import member="Service" contract="IMessageService" />      </imports>    </part>  </parts></mef.configuration>

Once that is done, you pretty much do like you would do with the Attributed Programming Model. You create a catalog, in this case a DefinitionProviderPartCatalog, but when you do that you need to tell it which provider to use.

var provider =    new ConfigurableDefinitionProvider("mef.configuration");var catalog =    new DefinitionProviderPartCatalog<ConfigurableDefinitionProvider>(provider);var batch =    new CompositionBatch();batch.AddProviderPart(this);var container =    new CompositionContainer(catalog);container.Compose(batch);

The ConfigurableDefinitionProvider needs to know the name of the configuration section in order to know where to find the information that is needed to manufacture the part definition. If you wanted to change this into using the fluent definition provider, all you would have to do would be to create a new instance of the FluentDefinitionProvider class and pass it to the catalog.

provider    .Import<Program>(p => p.Service)    .WithContract(typeof(IMessageService))    .Export<NullMessageService>(n => n)    .WithContract(typeof(IMessageService));var catalog =    new DefinitionProviderPartCatalog<FluentDefinitionProvider>(provider);

The FluentDefinitionProvided uses an Internal DSL to define that available parts. So with the help of the IDefinitionProvider interface you could easily implement a custom approach to defining definitions. You could read from a file on the network to allow for a shared definition file, or configure a cluster of MEF enabled applications with a single file. Or you could implement a definition provider that called a web service to get the definitions, or build a definition provider that used YAML or XAML, the possibilities are literally endless.


Object Factories

An object factory gives you control over an important step in the composition process – the creation of the part instance. This enables you to implement custom logic for how the instance should be created.


For example you could implement an object factory that returns AOP or remoting proxies instead of the actual objects.

public class NAspectObjectFactory : ObjectFactory{    public override object Create(Type type, params object[] parameters)    {        IEngine engine =            ApplicationContext.Configure();        object proxy =            engine.CreateProxy(type, parameters);        return proxy;    }}

You would then tell the model to use the factory by assigning an instance of it to the DefinitionProviderPartCatalog instance that you are using

var catalog =    new DefinitionProviderPartCatalog<FluentDefinitionProvider>(provider);catalog.Factory = new NAspectObjectFactory();

To read more about the object factory functionality of the provider model please refer to the Object Factories documentation section of the model at the MEF Contrib page.


Trusted Assemblies & Configuration

One of the features that’s currently being developed is the ability to tell a catalog which assemblies to trust. When an assembly is added to the trust list of a catalog then only parts defined in those assemblies will be returned by the catalog, all other will be discarded.


To give you an idea of what this will look like look at the following source code

provider    .Import<Program>(p => p.Service)    .WithContract(typeof(IMessageService))    .Export<NullMessageService>(n => n)    .WithContract(typeof(IMessageService));var catalog =    new DefinitionProviderPartCatalog<FluentDefinitionProvider>(provider);catalog.Configuration    .Trust(Assembly.GetExecutingAssembly())    .Trust(AppDomain.Current)    .Trust("some-public-key");

As you see there are quite a lot of overloads for specifying which assemblies to trust.


The Future

If you do find any bugs then please consider adding it to our issue tracker on codeplex or drop me a line. Equally if you have any suggestions for improvements of the code or the model itself, please post on the project discussion list on our codeplex page.


I’ll keep on adding more features as I think of them, but I'm also looking for people to actively help work on the model so if you are interested please let me know!


I would like to thank Glenn Block and Kathleen Dollard for taking the time to review the post while I was working on it.



Media_httpdotnetshout_wbcmb

Using a custom container to add default value support to MEF

The Managed Extensibility Framework does a great job of making it easy to write applications which are composed of discovered parts. One aspect of composing your application is that you can never quite know (unless its a private application where you have full control) which parts that will be available to the application, or even if there will be any parts at all. The latter is very important, you need to understand this so that you can build you application so that it doesn’t fail if an import cannot be satisfied, i.e. no matching exports were discovered.


Exactly how you build your application to handle when an import does not get satisfied is probably going to be on a case-by-case scenario, but the two most obvious approaches would be to either build in safe-guards to check for invalid import state (such as null value checks) or ensure that default values will be assigned to the imports if no exports were discovered.


MEF offers many different approaches to implementing support for default values. One approach is to take advantage of how MEF queries the export provider topology which gives you the possibility to implement different types of default value behavior (for example of the defaults should be overridable or not). I know the MEF team is planning to blog about this soon so I’ll not go into any details, but you should read Using ExportProviders to customize container behavior Part I by Glenn Block, Program Manager on the MEF team, for more information on ExportProviders and how they can be used to add custom functionality to the composition process.


As the title of this post suggestion, we are going to focus on how you can add support for default values using a custom container and a fluent interface. The following acceptance tests gives you an idea of what we are going to be building.


[Test]public void DefaultValueShouldBeUsedIfNoMatchingExportsAreFound(){    ContractBasedImportDefinition definition =        new ContractBasedImportDefinition(            "MessageService",            ImportCardinality.ZeroOrOne,            true,            false);    var defaultMessageService =        new DefaultMessageService();    var container =        new DefaultValueContainer();    container        .Register("MessageService")        .With(defaultMessageService);    var results =        container.GetExports(definition);    Assert.IsTrue(results.Count() == 1);    Assert.IsTrue(results.First().GetExportedObject().GetType() == typeof(DefaultMessageService));    Assert.AreSame(results.First().GetExportedObject(), defaultMessageService);}[Test]public void DefaultValuesShouldNotBeUsedIfMatchingExportsAreFound(){    FakeExportProvider provider =        new FakeExportProvider();    provider.AddExport("MessageService", new SmtpMessageService());    ContractBasedImportDefinition definition =        new ContractBasedImportDefinition(            "MessageService",            ImportCardinality.ZeroOrOne,            true,            false);    var defaultMessageService =        new DefaultMessageService();    var container =        new DefaultValueContainer(provider);    container        .Register("MessageService")        .With(defaultMessageService);    var results =        container.GetExports(definition);    Assert.IsTrue(results.Count() == 1);    Assert.IsTrue(results.First().GetExportedObject().GetType() == typeof(SmtpMessageService));}

The two acceptance tests verifies that the correct default value behavior is applied by the container. The first test ensures that the default value is returned when no exports could be located (notice that the container is not passed any catalog or export providers when it’s created so it has no way of finding any exports) and the second test ensures that the matching export (you can read more about the FakeExportProvider class in my previous post Creating a FakeExportProvider to help with testing MEF code) is returned instead of the available default value. The second test highlights an important aspect of the container behavior; the default values and discovered exports are mutually exclusive, meaning they will never be returned at the same time.


Implementing the container

The first thing that we need to do is to derive a new class, the DefaultValueContainer class, from the CompositionContainer (which can be found in the System.ComponentModel.Composition.Hosting namespace, don’t forget to add a reference to the System.ComponentModel.Composition assembly that you can download at the MEF project site).


/// <summary>/// Defines a <see cref="CompositionContainer"/> with the ability to register default/// values for a contract./// </summary>/// <remarks>/// The default values will only be returned if no matching exports was found for the/// import./// </remarks>public class DefaultValueContainer : CompositionContainer{    /// <summary>    /// Gets a list of <see cref="Export"/> objects which matches the provided <see cref="ImportDefinition"/>.    /// </summary>    /// <param name="definition">The <see cref="ImportDefinition"/> to get the exports for.</param>    /// <returns>An <see cref="IEnumerable{T}"/> object.</returns>    protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition)    {        throw new NotImplementedException();    }}

The GetExportsCore method, of the CompositionContainer class, is where we will later add the logic for returning the default values if the container didn’t discover any matching exports. We need to take care of a couple of things before we implement the GetExportCore method, first of all we need a place to store the default values that have been associated with a specific contract.


/// <summary>/// Gets or sets the default values./// </summary>/// <value>A <see cref="Dictionary{TKey,TValue}"/> object,.where the key is the contract name and the value is the default value collection for the contract.</value>[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Multiple default values need to be able to be stored for a contract.")][SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Derived instances should be able to write to this property.")]protected Dictionary<string, Collection<Export>> Defaults { get; set; }

It might look complicated but its not. It’s a normal C# auto-property with some FxCop rule suppressions added. The Default property is a dictionary which uses the contract name as the key and stores the default values in a collection. As the property declaration suggests, we are going to be storing Export objects instead of directly storing the default values. This makes sense since the GetExportCore method returns an IEnumerable of Exports, so instead of wrapping the default values right before they are returned we are going to wrap them when they are added to the container.


The second thing that the container needs are a set of constructor overloads. At a minimum the container should support the same overloads as the CompositionContainer class so that it makes easier to swap out the normal container with the DefaultValueContainer.


/// <summary>/// Initializes a new instance of the <see cref="DefaultValueContainer"/> class./// </summary>public DefaultValueContainer()    : this((ComposablePartCatalog)null){}/// <summary>/// Initializes a new instance of the <see cref="DefaultValueContainer"/> class, using/// the provided list of <see cref="ExportProvider"/> instances./// </summary>/// <param name="providers">A list of <see cref="ExportProvider"/> instances.</param>public DefaultValueContainer(params ExportProvider[] providers)    : this(null, providers){}/// <summary>/// Initializes a new instance of the <see cref="DefaultValueContainer"/> class, using/// the provided <see cref="ComposablePartCatalog"/> and list of <see cref="ExportProvider"/> instances./// </summary>/// <param name="catalog">The <see cref="ComposablePartCatalog"/> to add to the container.</param>/// <param name="providers">The list of <see cref="ExportProvider"/> instances to add to the container.</param>public DefaultValueContainer(ComposablePartCatalog catalog, params ExportProvider[] providers)    : base(catalog, providers){    this.Defaults = new Dictionary<string, Collection<Export>>();}

Now that the basic functionality have been added to the container we can turn our attention to writing an implementation of the GetExportsCore method. It’s inside this method that the default-value behavior is going to be implemented. The base implementation of this method already contains the code to try and retrieve a list of discovered exports which matches the provided import definition, so all we need to do is to add the code which should be executed when no matching exports was returned by the base implementation.


/// <summary>/// Gets a list of <see cref="Export"/> objects which matches the provided <see cref="ImportDefinition"/>./// </summary>/// <param name="definition">The <see cref="ImportDefinition"/> to get the exports for.</param>/// <returns>An <see cref="IEnumerable{T}"/> object.</returns>protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition){    var exports =        this.TryGetExportsCore(definition);    if (exports.Count() == 0)    {        var contractDefinition =            definition as ContractBasedImportDefinition;        if (contractDefinition != null)        {            string contractName =                contractDefinition.ContractName;            if (this.Defaults.ContainsKey(contractName))            {                return this.Defaults[contractName];            }        }    }    return exports;}

The implementation is very straight forward; the base class implementation is queried for matching exports and if any were discovered then they will be returned. In the event of no matching exports the internal collection of default values (remember they will be wrapped in export objects) will be checked to see if it contains any exports which could be returned instead. The TryGetExportsCore method is part of the container implementation and is responsible for calling the base class implementation of the GetExportCore method and in the event that no matching exports were discovered it will catch the CardinalityMismatchException that usually is thrown and instead returns an empty list of export objects.


/// <summary>/// Attempts to retrieve exports matching the provided <see cref="ImportDefinition"/>./// </summary>/// <param name="definition">The <see cref="ImportDefinition"/> to get the exports for.</param>/// <returns>An <see cref="IEnumerable{T}"/> object containing the matched if any was found; otherwise <see cref="Enumerable.Empty{TResult}"/>.</returns>protected IEnumerable<Export> TryGetExportsCore(ImportDefinition definition){    try    {        return base.GetExportsCore(definition);    }    catch (CardinalityMismatchException)    {    }    return Enumerable.Empty<Export>();}

Adding the fluent interface for manipulating default values

The adding and removing of available default values are going to be done through a fluent interface on the container. The interface will support registering a contract for default value support, adding default values for the contract and to unregistering a contract. The first thing we are going to have to be able to tell the container that we want it to support default values for a specific contract. To do this we are going to implement two overloads of the Register method.


/// <summary>/// Registers a contract so that default values can be assigned./// </summary>/// <param name="contractName">Then name of the contract to register default values for.</param>/// <returns>The current <see cref="DefaultValueContainer"/> object.</returns>/// <exception cref="ArgumentException">The provided value of the <paramref name="contractName"/> parameter was <see langword="null"/> or empty.</exception>public DefaultValueContainer Register(string contractName){    if (string.IsNullOrEmpty(contractName))    {        throw new ArgumentException("The name of the contract cannot be null or empty.");    }    if (!this.Defaults.ContainsKey(contractName))    {        this.Defaults.Add(contractName, new Collection<Export>());    }    return this;}/// <summary>/// Registers a <see cref="Type"/> as a contract so that default values can be assigned./// </summary>/// <param name="contractType">The <see cref="Type"/> to register as the contract.</param>/// <returns>The current <see cref="DefaultValueContainer"/> object.</returns>/// <remarks>The value of the <see cref="Type.FullName"/> property will be used as the contract.</remarks>/// <exception cref="ArgumentNullException">The provided value of the <paramref name="contractType"/> parameter was <see langword="null"/>.</exception>public DefaultValueContainer Register(Type contractType){    if (contractType == null)    {        throw new ArgumentNullException("contractType", "The contract type cannot be null.");    }    return this.Register(contractType.FullName);}

Implementing so that you can instruct the container that you no longer want it to add default value to a specific contract is just as simple. We do this by adding an Unregister method and provides the same two overloads as we did with the register method. Unregistering a contract will delete all records of it, including the associated default values, from the container,l


/// <summary>/// Unregisters a contract and removes all previously registered default values assigned to it./// </summary>/// <param name="contractName">The contract to unregister.</param>/// <returns>The current <see cref="DefaultValueContainer"/> object.</returns>/// <exception cref="ArgumentException">The provided value of the <paramref name="contractName"/> parameter was <see langword="null"/> or empty.</exception>public DefaultValueContainer Unregister(string contractName){    if (string.IsNullOrEmpty(contractName))    {        throw new ArgumentException("The name of the contract cannot be null or empty.");    }    this.Defaults.Remove(contractName);    return this;}/// <summary>/// Unregisters a contract and removes all previously registered default values assigned to it./// </summary>/// <param name="contractType">The <see cref="Type"/> to extract the contract name from.</param>/// <returns>The current <see cref="DefaultValueContainer"/> object.</returns>/// <remarks>The value of the <see cref="Type.FullName"/> property will be used as the contract.</remarks>/// <exception cref="ArgumentNullException">The provided value of the <paramref name="contractType"/> parameter was <see langword="null"/>.</exception>public DefaultValueContainer Unregister(Type contractType){    if (contractType == null)    {        throw new ArgumentNullException("contractType", "The contract cannot be null.");    }    this.Unregister(contractType.FullName);    return this;}

The final part of the fluent interface is to be able to add the actual default values. This is done with the help of the two overloads of the With method. The With method is responsible for associating the provided default value(s) with the contract that was last registered with the container. As previously mentioned we are going to wrap the default values in export objects when they are added to the container, making the With method the perfect place to add this functionality.


/// <summary>/// Adds a default value to the last registered contract./// </summary>/// <param name="defaultValue">The default value to add.</param>/// <returns>The current <see cref="DefaultValueContainer"/> object.</returns>/// <exception cref="ArgumentNullException">The provided value of the <paramref name="defaultValue"/> parameter was <see langword="null"/>.</exception>public DefaultValueContainer With(object defaultValue){    if (defaultValue == null)    {        throw new ArgumentNullException("defaultValue", "The default value cannot be null.");    }    Export wrapper =        new Export(this.Defaults.Last().Key, () => defaultValue);    this.Defaults.Last().Value.Add(wrapper);    return this;}/// <summary>/// Adds a collection of default values to the last registered contract./// </summary>/// <param name="defaultValues">The collection of default values to add.</param>/// <returns>The current <see cref="DefaultValueContainer"/> object.</returns>/// <exception cref="ArgumentNullException">The provided value of the <paramref name="defaultValues"/> parameter was <see langword="null"/>.</exception>public DefaultValueContainer With(IEnumerable defaultValues){    if (defaultValues == null)    {        throw new ArgumentNullException("defaultValues", "The default values cannot be null.");    }    foreach (var defaultValue in defaultValues)    {        this.With(defaultValue);    }    return this;}

And that’s really all there is to it! We’ve now implemented a custom composition container which supports mutually exclusive default values for imports that could not be satisfied with the help of discovered parts. The DefaultValueConainer will have the exact same behavior for imports, of contract that has not been registered for default value support, as the CompositionContainer class which is shipped with MEF, making it very easy to retrofit existing composition code that you may have in place.


How the container could be further extended

I could probably make this post two or three times the length if I covered some of the ideas I have on how the DefaultValueContainer class could be improved even more, but I’ll leave that up to you so you can tailor it for your exact specific needs.


Some of the ideas I’ve had along the way are


  • Constructor overload for injecting defaults when the container is instantiated

  • Extending the fluent interface to be able to control if defaults for a specific contract should be mutual exclusive or if a union consisting of the default values and discovered exports should be returned

  • Being able to unregister individual defaults on a specific contract

  • Adding support for notification events. Perhaps change the implementation of the defaults value so that it uses an ObservableCollection instead


Finally

You can download the full source code, including a suit of acceptance tests, at my codeplex.com page. There is a good chance that an implementation of this class will end up in the trunc of the MEF Contrib project, an open-source contribution project for the Managed Extensibility Framework, in the future so keep an eye on the project. If you would like to join the MEF Contrib project, please let us know!

Media_httpdotnetshout_xjeqv

Creating a FakeExportProvider to help with testing MEF code

If you don’t know what the purpose of an export provider in MEF is, then I recommend you to read Using ExportProvider to customize container behavior Part I by Glenn Block for an in-depth description. The short version is that the export providers it so serve exports to the composition container. In this post I am going to show how to create an export provider which serves instances of objects by allowing you to directly register them for a specific contract. The export provider can then be passed to the composition container and provide known exports.


The first thing we need to do it to create the skeleton for the export provider.

/// <summary>/// Defines an <see cref="ExportProvider"/> which allows you to add object instances as/// exports for a specific contract. The provider is useful when you need to test MEF/// code and need control over the available exports./// </summary>public class FakeExportProvider : ExportProvider{    /// <summary>    /// Gets a list of <see cref="Export"/> objects which matches the provided <see cref="ImportDefinition"/>.    /// </summary>    /// <param name="definition">The <see cref="ImportDefinition"/> to get the exports for.</param>    /// <returns>An <see cref="IEnumerable{T}"/> object.</returns>    protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition)    {        throw new NotImplementedException();    }}

Nothing out of the ordinary here. The class inherits the ExportProvider base class and provides a (stubb) implementation of the abstract method GetExportsCore. This method is there the main work of the export provider will happen. It’s responsible for inspecting the provided ImportDefinition and return any exports which have been registered for the same contract that the definition contains. We’ll get back to the method once we’ve gotten some other plumbing out of the way.


/// <summary>/// Defines an <see cref="ExportProvider"/> which allows you to add object instances as/// exports for a specific contract. The provider is useful when you need to test MEF/// code and need control over the available exports./// </summary>public class FakeExportProvider : ExportProvider{    /// <summary>    /// Initializes a new instance of the <see cref="FakeExportProvider"/> class.    /// </summary>    public FakeExportProvider()        : this(new Dictionary<ExportDefinition, Collection<Export>>())    {    }    /// <summary>    /// Initializes a new instance of the <see cref="FakeExportProvider"/> class, using    /// the provided exports.    /// </summary>    /// <param name="exports">A <see cref="Dictionary{TKey, TValue}"/> object, containing the initial exports.</param>    public FakeExportProvider(Dictionary<ExportDefinition, Collection<Export>> exports)    {        this.Exports = exports;    }    /// <summary>    /// Gets or sets the list of available exports.    /// </summary>    /// <value>A <see cref="Dictionary{TKey, TValue}"/> object.</value>    protected Dictionary<ExportDefinition, Collection<Export>> Exports { get; set; }     /// <summary>    /// Gets a list of <see cref="Export"/> objects which matches the provided <see cref="ImportDefinition"/>.    /// </summary>    /// <param name="definition">The <see cref="ImportDefinition"/> to get the exports for.</param>    /// <returns>An <see cref="IEnumerable{T}"/> object.</returns>    protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition)    {        throw new NotImplementedException();    }}

It might look like a lot of code, but remove the comments and you’ll notice that what have been added are two constructors and a property. The property is used to store the object instances for a contract when they are registered. Actually it’s storing the Export object which contains the information needed to return the object instance once it’s asked to, which is when the GetExportedObject method on the export object is called. This can either be an explicit call made by yourself or happen internally in MEF when the composition is taking place, such as when an import is of a specific type and not the lazy export type.


So we now have a way to store the the exports, but we also need a way to add them to the export provider in the first place. Sure there is a constructor overload which enables us to pass in a dictionary of contracts and exports but we need a more natural way of adding instances to the provider.


/// <summary>/// Adds an export with a specified contract name./// </summary>/// <param name="contractName">A <see cref="String"/> containing the name of the contract.</param>/// <param name="export">The object to add as an export.</param>public void AddExport(string contractName, object export){    var found =        from e in this.Exports        where string.Compare(e.Key.ContractName, contractName, StringComparison.OrdinalIgnoreCase) == 0        select e;    if (found.Count() == 0)    {        ExportDefinition definition =            new ExportDefinition(contractName, new Dictionary<string, object>());        this.Exports.Add(definition, new Collection<Export>());    }    Export wrapper =        new Export(contractName, () => export);    found.First().Value.Add(wrapper);}/// <summary>/// Adds a list of exports with a specified contract name./// </summary>/// <param name="contractName">A <see cref="String"/> containing the name of the contract.</param>/// <param name="exports">A list of objects to add as exports.</param>public void AddExports(string contractName, IEnumerable exports){    foreach (var export in exports)    {        this.AddExport(contractName, export);    }}

The AddExport and AddExports method enables us to register a single or a collection of instances for a specific contract. These methods can be called multiple times for the same contract since the internal store is checked if there is an ExportDefinition stored for the provided contract name or not. If there is then it will be used to add the provided object instance(s). The AddExport method takes care of all the necessary steps to convert the contract name into an ExportDefinition and the instances to Export objects.


The time has not come to return to the GetExportsCore method and implement the logic to return the exports (if there are any) which matches a requested contract.


/// <summary>/// Gets a list of <see cref="Export"/> objects which matches the provided <see cref="ImportDefinition"/>./// </summary>/// <param name="definition">The <see cref="ImportDefinition"/> to get the exports for.</param>/// <returns>An <see cref="IEnumerable{T}"/> object.</returns>protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition){    var contractDefinition =        definition as ContractBasedImportDefinition;    if (contractDefinition != null)    {        string contractName =            contractDefinition.ContractName;        if (!string.IsNullOrEmpty(contractName))        {            var exports =                from e in this.Exports                where string.Compare(e.Key.ContractName, contractName, StringComparison.OrdinalIgnoreCase) == 0                select e.Value;            if (exports.Count() > 0)            {                return exports.First();            }        }    }    return Enumerable.Empty<Export>();}

The method casts the provided ImportDefinition to a ContractBasedImportDefinition instance. It does this to be able to easily extract the requested contract name. The ContractBasedImportDefinition class is part of MEF and can be located in the the System.ComponentModel.Composition.Primitives namespace. Once the name of the contract has been extracted it checks if there are any exports registered for it and if there are they are returned. If no exports could be found then an empty list is returned.


Using the export provider is as easy as creating an instance, registering the instances for the contracts of your choice and pass the entire provider to the composition container. Pretend you had a class called DefaultMessageService that you wanted to be returned for the contract Foo. The below nUnit tests shows how you could use the FakeExportProvider to accomplish this.


[Test]public void ContainerShouldReturnInstancesRegisteredForTheContract(){    FakeExportProvider provider =        new FakeExportProvider();    provider.AddExport("Foo", new DefaultMessageService());        var container =        new CompositionContainer(provider);    ContractBasedImportDefinition definition =        new ContractBasedImportDefinition(            "Foo",            ImportCardinality.ZeroOrOne,            true,            false);    var results =        container.GetExports(definition);    Assert.IsTrue(results.Count() == 1);    Assert.IsTrue(results.First().GetExportedObject().GetType() == typeof(DefaultMessageService));}

Notice that no catalog has been provided to the CompositionContainer, the only source of exports are the instances we have registered in the FakeExportProvider that was passed into the constructor of the container. If the test was modified so that instances were registered for a Bar contract as well


FakeExportProvider provider =    new FakeExportProvider();provider.AddExport("Foo", new DefaultMessageService());provider.AddExport("Bar", new BarMessageService());

then the test will still pass since only the instances which has been registered for the requested contract will be returned. That’s all there is to it! You can download the full source code at my codeplex page and it’s very likely that an extended version of this export provider will end up in a future release of the MEF Contrib project.


Media_httpdotnetshout_mjilw