Posterous theme by Cory Watilo

The purpose of the ContractTypeAttribute in MEF

I will admit that the ContractTypeAttribute confused me a bit the first time I saw it and I bugged the MEF team about it, so thanks to them for having the patience to answer my (follow-up) questions!


The first thing you need to know is that this attribute is not a requirement when building MEF parts. Your application will not fail if you do not decorate your contract interfaces with it, nor will you be loosing any features inside of your application. So what is the purpose then?


The main purpose of the attribute, right now when the Preview 3 is the more recent release, is discoverability. By decorating your contracts with the attribute you will enable them to be discovered by tools. As far as I know there are no available tools (by Microsoft or the community) yet, but I don’t think it’s to far fetched to guess that Microsoft will ship a designer or other form of visual tool later when the framework has matured.


Imaging something along the line the class designer but where you get visual representation of your MEF parts, contracts, metadata, catalogs and so on. Imagine being able to go into a class designer, pull in MEF components and, from the designer, decorate your classes and their members with MEF information. That would be very cool and also very useful to keep track of the MEF integration that you are building into an application, especially if you are working in a team of developers.


So even though the framework itself doesn’t rely on the presence of the attribute, Microsoft recommends that you still use it to decorate your contracts and, if possible, also provide the metadata type in the contract declaration. There’s really nothing to loose and everything to gain right? I mean even if the only benefit you’ll ever get is to be able to look at an interface and instantly know that it’s being used together with MEF, it’s still worth it!


Please remember that this is how MEF Preview 3 treats the attribute. There’s nothing preventing Microsoft from making use of the attribute, inside of the framework itself, in later releases. In fact there is one thing the framework make use, today, of the attribute for; contract renaming.


Contract renaming

By default the contract name is the fully qualified name of the contract interface (you can read more about this in my previous post The difference between typed and named imports/exports in MEF) and MEF lets you modify this if you need to. Imagine you have a contract IContract


1: [ContractType]
2: public interface IContract
3: {
4:     void Verify();
5: }

You then create an import in your host application


1: [Import(typeof(IContract))]
2: public IContract Contract { get; set; }

And then someone creates an export


1: [Export(typeof(IContract))]
2: public class NullContract : IContract
3: {
4:     public void Verify()
5:     {
6:         Console.WriteLine("NullContract is verified!");
7:     }
8: }

Nothing fancy here, just your standard run-of-the-mill MEF scenario. Internally the framework will use the fully qualified type name of the IContract interface as the contract name. So when the CompositionContainer resolves import/export relationships this is the name it will use to match parts.


If you instead use the ContractTypeAttribute and provide a new name for the contract then, internally, MEF will resolve the typeof(IContract) to the new name of the contract instead of the fully qualified name. You can easily check this behaviour yourself by changing the definition of your import to


1: [Import(typeof(IContract))]
2: public Export<IContract> Contract { get; set; }

and them checking


1: this.Contract.Definition.ContractName

for when you use the default contract name and the overridden contract name and you will see the difference. Again, this is done internally in the ImportAttribute and ExportAttribute by calling CompositionService.GetContractName(Type type). If you look at the source code of the method


1: public static string GetContractName(Type type)
2: {
3:     Requires.NotNull(type, "type");
4:
5:     return GetContractNameFromContractTypeAttribute(type) ??
6:         ContractNameServices.GetDefaultContractName(type);
7: }

We see that it first tries to resolve the contract name from the ContractTypeAttribute, where the name override has higher presidency than the type name, and if that fails (i.e if the attribute isn’t present) then it falls back to resolving the default contract name.


Just a quick FYI. In the above example, it would have worked to use the overridden contract name in the import and keep using the typed contract for the export


1: [Import("SomeContractName")]
2: public IContract Contract { get; set; }

This means you can internally alter a contracts name without breaking exports depending on it.


I see a point in altering the contract name when you inspect imports and make decisions based on the name, but personally I’m going to stay away from ever using an overridden name in an import, it just ruins discoverability. Use typed contract names when ever possible!