Tuesday, July 26, 2011

Isolating MEF components

What Managed Extensibility Framework does well is component discovery and composition (when saying component I usually refer to MEF part). This is not a big surprise as it was designed to do so. However, one particular area where MEF has nothing to say about is component isolation. What is it ? Component isolation allows for plugins to work together without impacting each other. If one component fails, the rest of the system remains stable as nothing has ever happened. Yes, I know – when designing custom software solutions, we rarely care about plugins (too bad), but about component isolation, we don’t care at all. Why ? Most notably because dealing with component isolation is not an easy task. Since the best way to isolate components is to host them in a separate process, there has to be a fast IPC mechanism, and there is no single address space. Because we have calls across process boundaries, we have to serialize arguments on one side, deserialize them on the other, etc. Quite a bit of work there.

Some of you are probably familiar with System.AddIn namespace, better known as Managed Addin Framework. It has shipped long time ago, in .NET 3.0 if I remember well. This framework provides robust plugin infrastructure, and yes, it supports component isolation on App Domain and Process levels (okay there is also no isolation if you want to leverage plugins only). There is one problem with MAF, though. It has steep learning curve making it hard to jump into it. I never heard someone is using it in a production environment. Alternative ? Haven’t heard about yet. If you had, drop me a line please :)

Recently I have been thinking about creating custom component isolation mechanism and integrating it with Managed Extensibility Framework. Although not that straightforward, I managed to create special, dedicated catalog which can instantiate MEF parts in a separate AppDomain or even a separate process!

Meet the IsolatingCatalog

The IsolatingCatalog is responsible for doing all the magic. It is a decorating catalog, meaning it accepts another catalog, scans all its parts looking for those which need to be isolated, and then instantiates the parts accordingly. The API for the catalog is extremely simple. All you have to do is to tell MEF that a part has to be isolated. To do so, you can use custom export attribute or custom metadata attribute assuming you’re doing the export your way. Here is an example:

[IsolatedExport(typeof(IFakePart), Isolation = IsolationLevel.Process)]
public class FakePart1 : IFakePart
{
}

IsolatedExportAttribute is a custom export attribute which adds some metadata to the exported part, which is interpreted by the IsolatingCatalog so that it knows what to do with the export. The core property is the Isolation property of type IsolationLevel. Not surprisingly, it defines the isolation level for the part :) And the isolation level can be None (mostly used for testing only), AppDomain, and Process. I guess they are self explanatory. As I said, you can also use IsolatedAttribute, which is a custom metadata attribute.

[Export(typeof(IFakePart)), Isolated(Isolation = IsolationLevel.None)]
public class DisposableFakePart1 : IFakePart, IDisposable
{
}

What else can you define for an isolated export ? All properties are specified in the IIsolationMetadata interface which is defined as follows:

public interface IIsolationMetadata
{
/// <summary>
/// Gets the isolation for a part.
/// </summary>
IsolationLevel Isolation { get; }

/// <summary>
/// Indicates if a new host should be created for a new instance of the part.
/// </summary>
bool HostPerInstance { get; }

/// <summary>
/// Gets the name of the isolation group. Used to make sure parts which
/// defined the same name will be hosted in the same activation host.
/// </summary>
string IsolationGroup { get; }
}

With HostPerInstance property you can instruct the runtime to create separate host each time a part is created. I will cover hosts in much more details later on, right now a host is an activation host which, heh, hosts the instance of the created part. And IsolationGroup property is nothing more than a name for the activation host. If two or more parts specify the same name, they will be hosted in the same activation host, be in a separate AppDomain or a process. Note this interface is implemented by both the custom export and custom metadata attribute ensuring you can achieve the same results using either of the approaches.

Last thing to cover, although pretty straightforward, is how to use the catalog itself. As I said, it is a decorating catlog, and there is no philosophy is setting it up:

var typeCatalog = new TypeCatalog(typeof(TempPart), typeof(FakePart1));
var isolatingCatalog = new IsolatingCatalog(typeCatalog);
var container = new CompositionContainer(isolatingCatalog);

var part = container.GetExportedValue<TempPart>();

Let’s stop here for one second, and let’s assume FakePart1 is instantiated in isolation, with TempPart consuming it:

[Export]
public class TempPart
{
[Import]
public IFakePart Part { get; set; }
}

What gets injected into Part property ? If we run this code in debug mode, we would see this:

FakePartProxy

This is very important. What gets injected is a proxy supporting the IFakePart contract rather than a concrete FakePart1 implementation. Why ? Of course because the original FakePart1 is instantiated in isolation, typically in a separate process or AppDomain, so what the client gets is a proxy which serializes all calls to the concrete implementation. Seems obvious, but I wanted to stress it :)

Demo

Now that you have seen how to make isolated parts, it’s time for a little demo. I put a simple app (I took a simple MDI sample from Caliburn project) which displays “movies” from various providers. It shouldn’t be a surprise that each movie provider is a MEF part, and some of them are working properly, and some of them are not.

image

Lets have a quick look at how each provider is exported:

[IsolatedExport(typeof(IMovieProvider), HostPerInstance = true, Isolation = IsolationLevel.Process, IsolationGroup = "SomeName")]
public class Provider1 : IMovieProvider
{
}

You can see that each provider is instantiated in a separate, named activation host. However, because all providers specify the same IsolationGroup, there will be a separate process per each three instances of the providers. Also, the app supports tabbed interface, with each tab getting its own set of providers. This means each tab will have its own process hosting the providers, which can easily be verified in the Task Manager (three tabs above means three processes below):

TaskManager

This mimics the Google Chrome browser approach, where each tab is hosted in a separate process. Okay, lets break something. Provider 3, when executed 2 times, will throw an exception on a separate thread. This is of course by design :) What will happen ? Normally, the application would crush and the process would terminate. However, because the logic which will fail is hosted in a separate process, that process would crush leaving the main app intact. As if this was not enough, the API allows to intercept failures, giving the ability to display error to the user:

image

As you see, even though there was a critical error in one of the providers, the application remains stable. If we go to the Task Manager we will see two processes hosting the providers, as the third one just failed. Btw, make sure you manually copy PluginContainer.exe (this guy can host MEF parts in it) to the bin folder. In feature releases, I will link this assembly directly to IsolatingCatalog.

Lack of features

Although working, this solution is not perfect. One of the drawbacks is that if a developer wants to isolate a part, it has to be exported accordingly. I think it would be nice to have the ability to setup isolation on the import level, so that even though the part developer didn’t plan for isolation, the import side would switch the isolation on. I imagine there would be IsolatedImportAttribute which could do the trick. The other thing is I’m using WCF for IPC. At first it seems okay, but creating WCF host is a costly operation, thus you will notice a slight delay when opening new tabs in the above demo. Perhaps it would be good to craft custom IPC based on named pipes ? Last thing is lack of dependency injection, since we might operate in a different address space. The good news is that it should be possible to address this; WCF supports duplex channel communication on named pipes binding, so I could use proxy to communicate back with the host application. This is pending on my TODO list :)

Download

Although namespace suggests IsolatingCatalog is part of MefContrib, it is not. It’s not because this is a POC rather than something production ready. I wrote it mainly to prove it is possible to isolate MEF parts. Having said that, I think the approach chosen is good (inproc WCF with named pipes binding is used for the IPC purposes), and I would love to see this being part of MefContrib someday. The only thing is time needed to add more test cases, doing a cleanup, etc. If you feel you could help me with that, drop me a line and we can work together!

To download the IsolatingCatalog, just go to my MefContrib fork and download isolation branch. The demo presented above can be downloaded from my skydrive below.



Conclusion

This post covered a working solution which enables to activate MEF parts in a separate AppDomain or even a separate process. Next post will cover how the isolation is being handled by IsolatingCatalog. Although not yet completed, my approach seems working fine, and after extensive testing I think it will make its way to the MefContrib. In the meantime, if you feel you could contribute to that catalog, either from MEF or isolation perspectives, fell free to contact me so that we might exchange ideas, etc. Hope you liked it!

Saturday, April 9, 2011

Introducing convention based programming for Managed Extensibility Framework

More than a year ago my friend @TheCodeJunkie wrote a very nice addition to Managed Extensibility Framework – the ConventionCatalog. Since then it’s a part of MefContrib project. However, I haven’t seen many people using it. My guess is that there is no much information about it, besides this post. So in this post I will discuss what a convention model is, and how to use it!

What is ConventionCatalog ?

Convention model (aka. ConventionCatalog) allows you to specify conventions to produce parts, exports and imports. Okay, this is all fine, but give me an example! Here is a convention you can define: For every type in assembly MyCompany.MyFantasticProgram, if a type implements IWidget, please export it with contract type IWidget and import property named ViewModel. Nice, huh? Say you have Widget1 and Widget2 classes implementing IWidget interface. image They will be automatically exported, and moreover, they don’t have to be attributed using standard MEF attributes!!! This is because the ConventionCatalog defines an extensible mechanism for writing such conventions! And you can write your own easily! One thing to note about the above convention – it will be applied to many types, particularly all implementing the IWidget interface. This is important as you don’t have to explicitly export all the classes individually. At the same time, it is perfectly legal to apply a convention to a single type. Example? If you ever encounter Widget123 type, please export it using IWidget contract type and add Location metadata with a value of Location.Left (enumeration). Here, only a single class (part) will be affected – the Widget123 class. Now you have a pretty good understanding what conventions are in the beautiful world of MEF, but how can I specify them in a program ? So as I stated previously, the catalog is extensible, so.. any possible way of specifying the conventions is… possible! Originally, @TheCodeJunkie developed a pretty nice fluent interface for defining them (as part of MefContrib 1.1 I’ve added some extension methods to ease the use of fi). Here is a code which defines the initial convention (it does not specify where to look for the types to apply it – be patient)

Part()
.ForTypesAssignableFrom<IWidget>()
.ExportAs<IWidget>()
.ImportProperty("ViewModel");


Recently, I have developed a registration mechanism which enables to specify parts via the configuration file – App.config. Next section outlines both methods using a simple use case.



How can I use it ?



Let’s begin with a simple scenario. Let’s build a console application which can display a list of movies from various data sources. Here are the main classes and interfaces involved in the design: MovieClasses The core interface is IMovieProvider which provides an abstraction over any movie repository and has only one method returning a list of movies from a single movie source. It also has two dummy implementations – nothing interesting. This interface is consumed by the MovieLister class which implements IMovieLister and acts as a facade on top of the providers. It simply returns all movies from all providers available, with optional filtering by movie title. MovieLister also performs some simple logging, and the logger is injected using the constructor injection. The complete code for that class is right here:



public class MovieLister : IMovieLister
{
private readonly ILogger _logger;

public MovieLister(ILogger logger)
{
_logger = logger;
}

public IMovieProvider[] Providers { get; set; }

public IEnumerable<Movie> GetMovies()
{
var movies = Providers
.SelectMany(movieProvider => movieProvider.GetMovies())
.ToList();

_logger.Log(string.Format("Loaded {0} movies.", movies.Count));

return movies;
}

public IEnumerable<Movie> GetMoviesByName(string name)
{
var movies = GetMovies()
.Where(m => m.Name.Contains(name))
.ToList();

_logger.Log(string.Format("Found {0} movies matching '{1}'.", movies.Count, name));

return movies;
}
}

Note that there is no sign of standard MEF Export/Import attributes, and the constructor is not attributed with ImportingConstructor! Finally, there is a Program class which wraps the app. Here’s the code:

public class Program
{
[Import]
public IMovieLister MovieLister { get; set; }

public static void Main(string[] args)
{
var p = new Program();
p.Init();
p.Run();
}

private void Init()
{
var conventionCatalog = new ConventionCatalog(new MoviePartRegistry());
var container = new CompositionContainer(conventionCatalog);

// Composing this part will inject MovieLister property
container.ComposeParts(this);
}

private void Run()
{
var movies = MovieLister.GetMoviesByName("Movie");
foreach (var movie in movies)
{
Console.WriteLine(movie.Name);
}
}
}

No doubt the most interesting part in the above code is the Init() method. I create there the ConventionCatalog (note this is the only catalog used in this example) and pass an instance of some registry. And here we came to the very important thing: all conventions are defined (or I should rather say can be understood) thanks to the IPartRegistry interface. So to introduce a custom way of defining  conventions, you have to implement that interface (if you want to understand some internals of how ConventionCatalog works, read this post). By default, MefContrib 1.1 ships with two implementations:


  • PartRegistry – this class provides fluent interface to register part/export/import conventions,


  • ConfigurationPartRegistry – this class provide the XML way of specifying conventions.


Okay, so let’s see what it takes to register our parts using fluent interface.

public class MoviePartRegistry : PartRegistry
{
public MoviePartRegistry()
{
// Apply the conventions to all types int the specified assembly
Scan(c => c.Assembly(typeof(Program).Assembly));

Part<MovieLister>()
.MakeShared() // make this part shared
.ExportAs<IMovieLister>() // and export it with contract type IMovieLister
.ImportConstructor() // use constructor injection
.Imports(x =>
{
x.Import<MovieLister>() // import on part MovieLister
.Member(m => m.Providers) // member named 'Providers'
.ContractType<IMovieProvider>(); // with contract type IMovieProvider
});

Part()
.ForTypesAssignableFrom<IMovieProvider>()
.ExportAs<IMovieProvider>();

Part<LoggerImpl>()
.MakeShared()
.ExportAs<ILogger>();
}
}

I derive from PartRegistry (although this is not a requirement, I prefer to do this that way) and do two things there. First, I specify to which types I want to apply my conventions. This is done through a nice lambda expression. What it does under the hoods ? It creates appropriate type scanners. A type scanner (anything implementing ITypeScanner interface) is responsible for returning all the types for which the user wants to assign conventions, if there are any applicable). Out of the box, there are:


  • TypeScanner, which can return user specified types,


  • AssemblyTypeScanner – returns all the types from given assembly,


  • DirectoryTypeScanner – returns all the types from all assemblies from a given disk folder,


  • AggregateTypeScanner – aggregates types from various type scanners.


Does it resemble you something ? Yes! Catalogs from MEF of course! This is because MEF catalogs are responsible for pulling parts/exports/imports from types. Similarly, we obtain types for which we want to apply the conventions. Okay, that’s all in terms of how to specify types for conventions. Lets move on to how to actually specify a convention. There’s a single method called Part() which returns PartConventionBuilder which has a nice fluent API to define part conventions. Part() method comes in two flavours – generic and nongeneric. The difference is that the generic Part<PartType>() method creates a convention in a strongly typed manner and applies that convention only to the part type specified as a generic type argument. However, if you want to leverage strong typing and specify conventions for other types as well, you can force it using ForTypesAssignableFrom() method. Actually, to specify types for which you want to apply the convention, you can use any of the For*() methods. It would be pointless to further explain the API, please play with it and let us know how does it feel – we can always improve! You probably have noticed how nicely IMoveProvider instances are exported. But what if we wanted to be able to specify which providers we want to use ? Of course there are many ways of achieving this, including leveraging metadata facilities of MEF. One method could also be to specify movie providers in the App.config file rather than exporting all IMovieProvider implementations using a convention. Let’s explore that possibility.


To configure parts using XML, we need to add another part registry to convention catalog. Change the Init() method to this:

private void Init()
{
var conventionCatalog = new ConventionCatalog(
new ConfigurationPartRegistry("mef.configuration"),
new MoviePartRegistry());
var container = new CompositionContainer(conventionCatalog);

// Composing this part will inject MovieLister property
container.ComposeParts(this);
}

ConfigurationPartRegistry class accepts a string representing the name of the config section used to configure parts. Next, remove the fluent registration for IMovieProviders. Finally, add the App.config with the following content:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="mef.configuration"
type="MefContrib.Hosting.Conventions.Configuration.Section.ConventionConfigurationSection, MefContrib" />
</configSections>

<mef.configuration>
<parts>

<part type="ConventionCatalogDemo.MovieProvider1, ConventionCatalogDemo" creationPolicy="Shared">
<exports>
<export contractType="ConventionCatalogDemo.IMovieProvider, ConventionCatalogDemo" />
</exports>
</part>

<part type="ConventionCatalogDemo.MovieProvider2, ConventionCatalogDemo" creationPolicy="Shared">
<exports>
<export contractType="ConventionCatalogDemo.IMovieProvider, ConventionCatalogDemo" />
</exports>
</part>

</parts>
</mef.configuration>

</configuration>

Well, what do we have in here ? :) We have a MEF configuration specifying a set of parts. Each part must have a full .NET type associated with it (type name + assembly). The part (not surprisingly) can have a set of exports it offers and of course a set of imports it consumes. Each export can specify:


  • contractType – type of the contract,


  • contractName – name under which the export will be available,


  • member – name of the member of the part to export (leave empty to export the whole part itself),


  • metadata – a collection of metadata-items specifying metadata that will be attached to the export.


Each import can specify:


  • contractType – type of the contract,


  • contractName – name used to resolve the import,


  • member – name of the member of the part to import,


  • creationPolicy – required creation policy,


  • allowDefault – whether the import allow default values,


  • isRecomposable – whether the import is recomposable,


  • required-metadata – a collection of metadata-items specifying required metadata.



To specify a set of imports for a part use imports xml element and fill it with import xml elements. I guess everything is self explanatory. If you have any doubts, pleas see MefContrib.Tests project to see some more examples.



Where can I find it ?



ConventionCatalog discussed in this post is available in MefContrib project. New ConfigurationPartRegistry ships as part of the MefCotrinb 1.1. Please download sources and binaries from mefcontrib.com. Sample code used in this post can be downloaded here. There is also another sample application (WPF based), which shows how ConventionCatalog can be used. You can download it from our official MefContrib-Samples Github repository. Here’s the screenshot for that app: ExtensibleDashboardOnConventions Enjoy and let me know if you like it!

Tuesday, March 29, 2011

Integrating Castle Windsor with MEF

Some time ago I developed a small chunk of code which enabled Unity and Managed Extensibility Framework to consume each others components (see my posts here and here). After a while I hooked up with @TheCodeJunkie who was, and still is, responsible for managing MefContrib project, which aims at delivering high quality MEF extensions developed by the community. Soon, my integration layer became a part of that library! Yeah, I was excited =) After a while, I posted a refined version. Basically, I extracted some generic code from the existing Unity integration stuff which could be reused with other DI containers. So in this post I want to discuss a simple adapter for Castle Windsor which is built using that infrastructure and enables MEF to consume components registered in Windsor container.

Implementation

All the required stuff lives in MefContrib.Containers namespace (MefContrib.dll assembly) which has been renamed from MefContrib.Integration as the new name is more meaningful. There is one interface and one ExportProvider which are interesting in this scenario. IContainerAdapter is an interface which encapsulates basic behaviour of a typical IoC container. The ContainerExportProvider class then uses that interface to extract relevant components from the IoC and provides them to MEF. So the only part missing from the equation is the actual IContainerAdapter implementation for Windsor Container. Unsurprisingly, it is very simple. Here it comes:

public class WindsorContainerAdapter : ContainerAdapterBase
{
private readonly WindsorContainer _container;

public WindsorContainerAdapter(WindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}

_container = container;
_container.Kernel.ComponentRegistered += ComponentRegisteredHandler;
}

private void ComponentRegisteredHandler(string key, IHandler handler)
{
RegisterCastleComponent(handler);
}

public override object Resolve(Type type, string name)
{
return name == null
? _container.Resolve(type)
: _container.Resolve(name, type);
}

public override void Initialize()
{
var handlers = _container.Kernel.GetAssignableHandlers(typeof (object));
foreach (var handler in handlers)
{
RegisterCastleComponent(handler);
}
}

private void RegisterCastleComponent(IHandler handler)
{
var name = handler.ComponentModel.Name;
var type = handler.Service;

// By default, Windsor assigns implementation's full name for the key,
// but for a default key we want to pass null instead
if (handler.ComponentModel.Implementation.FullName == name)
{
name = null;
}

OnRegisteringComponent(type, name);
}
}


All we have to do is to inform ContainerAdapterBase that a component has been registered within the container so that the ContainerExportProvider knows which types are available. In the Initialize method we have a chance to register components which were registered in the IoC container before the adapter had a chance to intercept this information itself. The Resolve method will be called by MEF in order to get a component from IoC.

Usage

The usage is pretty straightforward. Let’s assume we have IFoo service which maps to Foo implementation. Here’s the code which registers these types within Castle Windsor and then IFoo is consumed by MEF.

var windsorContainer = new WindsorContainer();
var provider = new ContainerExportProvider(new WindsorContainerAdapter(windsorContainer));
var compositionContainer = new CompositionContainer(provider);

// Setup Castle Windsor
windsorContainer.Register(Component.For<IFoo>().ImplementedBy<Foo>());

var fooExport = compositionContainer.GetExport<IFoo>();

Of course, named registration is supported. Also MEF can resolve all IFoo implementations if it happens that IFoo is mapped to more than one implementation (thanks to named registration). See all the tests available in the provided solution. 

Where can I find this ?

This code with some NUnit tests is available as a sample for the MefContrib project. You can find its sources at https://github.com/MefContrib/MefContrib-Samples.

Enjoy!

Tuesday, March 22, 2011

Geeks On Tour – Me speaking about MEF/MefContrib / Extensibility

3rd-Geeks-on-Tour logo

I’m happy to announce that between April 18th and 20th 2011 I will be speaking on Geeks on Tour roadshow! Three days, three cities – Katowice, Wrocław, Poznań, two presentations each day. Wondering what MEF is ? How does it relate to IoC and Managed Addin Framework ? When to choose which ? What’s MefContrib and how it can help you ? How to write your custom MEF extensions ? Join me on the talks to find out this and many more! You can find more details about the event, including detailed agenda, on geeksontour.pl official page!

I will be covering all the aspects regarding MEF, its strong and week sides, how does MEF relate to other technologies. I will be showing some of the cool features MEF team is preparing as part of MEF 2 release. I will show some cool features which are part of MefContrib project. Finally, I will deep dive into MEF internals, I will show how to write custom exporters and catalogs. The presentations will be held in Polish. Entrance is free :) See you there!

Presentation and full source code is available below.

Sunday, December 19, 2010

Introduction to InterceptingCatalog – Part II – Open Generics Support

In the previous post I have described how to setup interception using the InterceptingCatalog and InterceptionConfiguration class. Just to remind you, the interception allows you to take control over the exported instances thanks to the IExportedValueInterceptor interface. Although this is the primary functionality, there is other bunch of stuff possible to do with the catalog. In this post I am going to show how to enable open-generics support for MEF using both the InterceptingCatalog and the decorating GenericCatalog. I will then introduce the IExportHandler interface which gives the ability to do some nice filtering based on a given criteria as well as to add new exports on the fly. The open generics support implementation is based on the on the fly export creation (thanks to the IExportHandler interface) as well as thing called part rewriting. Keep reading to find out more!

The problem

One of the biggest problem people complain about is the lack of open-generics support in MEF. You can read about this issue here, here and here (I advise you see these entries!). The canonical example folks use concerns IRepository<T>. Imagine the following code:

public interface IRepository<T>
{
T Get(int id);

void Save(T instance);
}

[Export(typeof(IRepository<>))]
public class Repository<T> : IRepository<T>
{
public T Get(int id)
{
return (...);
}

public void Save(T instance)
{
Console.WriteLine("Saving {0} instance.", instance.GetType().Name);
}
}

/// <summary>
/// Fake customer.
/// </summary>
public class Customer { }

[Export]
public class CustomerViewModel
{
[Import]
public IRepository<Customer> Repository { get; set; }
}

So what happens here ? We simply export a generic implementation of the generic interface IRepository<T> with an open-generic contract type, and we import a closed-generic part based on the open generic contract. Unfortunately, this isn’t supported out of the box in MEF. However, thanks to MefContrib, it is!

How can I get it ?

Open generics support shipped initially in the MefContrib 1.0 release. However, it had limited capabilities as the open generics worked only when generic types were exported using the InheritedExport attribute. To get the updated version, which enables to do things like the above, you have to download MefContrib repo and compile the sources yourself. Updated samples, including those presented here, are available in the MefContrib-Samples repo. Go and get them =)

Container setup

There are two ways of enabling open generics support. You can either use more verbose syntax using the InterceptingCatalog, or you can leverage the GenericCatalog. The GenericCatalog is noting more than a convenient decorating catalog which internally uses the InterceptingCatalog.

The first thing to do is to provide mapping between open generic interface and its implementation. This step is mandatory since the underlying infrastructure requires to produce export based on the concrete implementation. This export is produced on the fly, which means it is not contained in any composable catalog, but is created when it is needed. To map the contract type to its implementation you can either implement IGenericContractRegistry interface or inherit the GenericContractRegistryBase class. The implementation which supports the above example is presented below.

[Export(typeof(IGenericContractRegistry))]
public class MyGenericContractRegistry : GenericContractRegistryBase
{
protected override void Initialize()
{
Register(typeof(IRepository<>), typeof(Repository<>));
}
}

Important: the mapping is required only when you export the generic class with explicitly given contract type (like in the example). If you export generic class with its default contract type, no mapping is required!

Next is what you have probably expected – the catalog setup.

// Create source catalog
var typeCatalog = new TypeCatalog(typeof(CustomerViewModel), typeof(MyGenericContractRegistry));

// Create the interception configuration and add support for open generics
var cfg = new InterceptionConfiguration()
.AddHandler(new GenericExportHandler());

// Create the InterceptingCatalog and pass the configuration
var interceptingCatalog = new InterceptingCatalog(typeCatalog, cfg);

// Create the container
var container = new CompositionContainer(interceptingCatalog);

// Get the repository
var repository = container.GetExportedValue<CustomerViewModel>().Repository;
After creating the interception configuration, we add the GenericExportHandler instance which is responsible for creating closed generic parts. This class implements the IExportHandler interface, which I will introduce in a moment. Meanwhile, let’s see the less verbose and cleaner setup routine.

// Create source catalog
var typeCatalog = new TypeCatalog(typeof(CustomerViewModel));

// Create catalog which supports open-generics, pass in the registry
var genericCatalog = new GenericCatalog(new MyGenericContractRegistry());

// Aggregate both catalogs
var aggregateCatalog = new AggregateCatalog(typeCatalog, genericCatalog);

// Create the container
var container = new CompositionContainer(aggregateCatalog);

// Get the repository
var repository = container.GetExportedValue<CustomerViewModel>().Repository;

Instead of creating the InterceptingCatalog, the GenericCatalog is created. This concludes how to setup MEF to support open generics. Next sections explain how stuff works, without digging into implementation details though. If you are curious, keep reading!

How does it work ?

You are maybe asking yourself – given the export definition below – how does MEF know that when importing say IRepository<Order>, it should inject Repository<Order> ?!
[Export(typeof(IRepository<>))]
public class Repository<T> : IRepository<T>
{
}

In fact MEF only knows there is an export Repository<T> which is NOT the required one! And this is not the only question! Attentive reader will also observe the the contract type (which is a string) of the given export will be ‘SomeCleverNamespace.IRepository()’ which is an open generic. But the import’s contract type will be ‘SomeCleverNamespace.IRepository(SomeOtherCleverNamespace.Order)’ which is a closed generic. So even though MEF somehow knew the export Repository<Order>, the contract types wouldn’t match resulting in ImportCardinalityMismatchException.

The answer to the first question is on the fly export creation. Earlier I have introduced the concept of mapping contract type to its implementation(s). So when we import IRepository<>, MEF knows its implementation is Repository<>. But of course we import closed generic, like I said IReposiotry<Order>, so MEF knows the implementing type is Repository<Order>. Of course there is no export Repository<Order>, only Repository<T>. So it have to be introduced in runtime! This is where IExportHandler comes to play. The open generics support is all implemented in the GenericExportHandler class which is responsible for creating closed generic exports on the fly.

Finally, the answer to the second question is part rewriting. When we create Repository<Order> export on the fly (I mean in runtime), the export’s contract type will remain ‘SomeCleverNamespace.IRepository()’. So we have to rewrite the part so that the contract type and optionally contract name will be set properly. To do the part rewriting, special catalog is used – GenericTypeCatalog. It accepts two types – the concrete type being exported (e.g. Repository<Order>) and the open-generic contract type (e.g. IRepository<>). What the catalog does in its internals is to rewrite all open-generic exports which match the contract type to be closed-generic. In our example, the contract type will be rewritten from ‘SomeCleverNamespace.IRepository()’ to ‘SomeCleverNamespace.IRepository(SomeOtherCleverNamespace.Order)’. Same for contract name.

Meet the IExportHandler interface

The purpose of this interface is to filter out exports based on any criteria you want, as well as to dynamically create new exports. Let’s have a look at the IExportHandler signature.

public interface IExportHandler
{
void Initialize(ComposablePartCatalog interceptedCatalog);

IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>>
GetExports(
ImportDefinition definition,
IEnumerable<Tuple<ComposablePartDefinition,ExportDefinition>> exports);
}

Wow! This looks complicated! Hopefully, it is not :) The initialize method gets called once when the export handler is initialized. Within this method you get a reference to the catalog being intercepted. The main player here is the GetExports method which has the exact same signature as the GetExports method in the ComposablePartCatalog class. It is called whenever an InterceptingCatalog is asked for exports which match the given import. The import definition is passed as the first argument. The second argument is a collection of matching export definitions along with theirs ComposablePartDefinition instances. The initial collection is the collection of exports from the intercepted catalog. Because the method returns the collection of matching exports, we can filter out the original exports we don’t want to show up, or what is more interesting, we can add our own export definitions!

Known limitations

Although support for open-generics in MefContrib is pretty amazing, it is not perfect. The first and probably the biggest limitation is the lack of support for recomposition. The other problem is that type being imported is inferred from the language construct rather than the import itself. Consider the following two imports.

[Import]
public IRepository<Order> OrderRepository { get; set; }

[Import(typeof(IRepository<Order>))]
public object OrderRepository { get; set; }

Both imports are perfectly legal. But only the former works as expected. This is because the type being imported is inferred from the property’s type, which is IRepository<Order>. In the latter example, the contract type is explicitly given in the Import attribute, but the property’s type is object, hence the inferred type will be object, which is not the case. You may want to know why is that. As you probably know, the import in MEF is represented by the ImportDefinition class. Unfortunately, it is NOT possible to get the Type instance representing the import from the ImportDefinition instance, only the defining construct (like property, field, etc.) and only for those ImportDefinition instances created by MEF’s Reflection Model.

Conclusion

In this post I have presented MefContrib’s approach to enable open-generic type composition. Hope you like it!

Tuesday, December 14, 2010

MEF Deep Dive Talk

Recently, I gave 2 talks about Managed Extensibility Framework. One on KGD.NET, which is our local .NET group (on Nov 24th 2010), and one on IT Academic Day at Uniwersytet Jagielloński in Kraków (Dec 14th 2010). Both of my talks went good! I do enjoy spreading knowledge about MEF and MefContrib! When it comes to the presentations, both were mostly the same, although on ITAD I was speaking more about MEF itself and less about hard stuff, so it was kind a MEF Deep Dive Light Edition =) I covered the following:

  1. Basics of developing loosely coupled components
  2. MEF basics (parts, exports, imports, composition)
  3. Catalogs
  4. Metadata
  5. Custom export attributes
  6. Recomposition
  7. Stable composition
  8. Debugging MEF
  9. MefContrib
  10. MEF Extensibility

You can find all the materials (slides + source code) from the KGD.NET meeting here and from the ITAD here. If you haven’t attended any of the talks, you might still want to go through the slides (these are nice!) and run the demos (VS 2010). Finally, I want thank Mike Taulty for letting me use some of the slides from his MEF talk =)

Saturday, December 4, 2010

MatrixAnimation for WPF

Windows Presentation Foundation has a powerful animation system. It comes with various classes which enable dependency properties’ values to be animated, i.e. to be automatically changed during a given period of time. WPF supports four types of animations:

  • Linear animation – a value of a property linearly changes from a starting value (referred as From) to a destination value (referred as To).
  • Key frame animation – animation is specified using key frames, each key frame specifies the time and the desired value. The animated property will be assigned once the timeline hits the give time.
  • Path-based animation – property value is given by a geometric path.
  • Frame-based animation – this is the most powerful animation approach, the CompositionTarget class is used to create custom animations based on a per-frame callback.

The first three animation types are supported by <Type>Animation, <Type>AnimationUsingKeyFrames and <Type>AnimationUsingPath classes, respectively. For example, consider the double type. Its animation is supported by DoubleAnimation, DoubleAnimationUsingKeyFrames and DoubleAnimationUsingPath classes.

WPF also supports matrix animations. However, out of the box, only key frame and path-based animations are supported for the Matrix type. This post introduces MatrixAnimation class, which performs linear, smooth animation of the Matrix type. The animation supports translation, scaling and rotation along with easing functions. The following 14 sec-length video shows an early preview of a multi-touch MDI interface whose windows are being animated using the MatrixAnimation class.

The following code snippet represents the MatrixAnimation class.
public class MatrixAnimation : MatrixAnimationBase
{
public Matrix? From
{
set { SetValue(FromProperty, value); }
get { return (Matrix)GetValue(FromProperty); }
}

public static DependencyProperty FromProperty =
DependencyProperty.Register("From", typeof(Matrix?), typeof(MatrixAnimation),
new PropertyMetadata(null));

public Matrix? To
{
set { SetValue(ToProperty, value); }
get { return (Matrix)GetValue(ToProperty); }
}

public static DependencyProperty ToProperty =
DependencyProperty.Register("To", typeof(Matrix?), typeof(MatrixAnimation),
new PropertyMetadata(null));

public IEasingFunction EasingFunction
{
get { return (IEasingFunction)GetValue(EasingFunctionProperty); }
set { SetValue(EasingFunctionProperty, value); }
}

public static readonly DependencyProperty EasingFunctionProperty =
DependencyProperty.Register("EasingFunction", typeof(IEasingFunction), typeof(MatrixAnimation),
new UIPropertyMetadata(null));

public MatrixAnimation()
{
}

public MatrixAnimation(Matrix toValue, Duration duration)
{
To = toValue;
Duration = duration;
}

public MatrixAnimation(Matrix toValue, Duration duration, FillBehavior fillBehavior)
{
To = toValue;
Duration = duration;
FillBehavior = fillBehavior;
}

public MatrixAnimation(Matrix fromValue, Matrix toValue, Duration duration)
{
From = fromValue;
To = toValue;
Duration = duration;
}

public MatrixAnimation(Matrix fromValue, Matrix toValue, Duration duration, FillBehavior fillBehavior)
{
From = fromValue;
To = toValue;
Duration = duration;
FillBehavior = fillBehavior;
}

protected override Freezable CreateInstanceCore()
{
return new MatrixAnimation();
}

protected override Matrix GetCurrentValueCore(Matrix defaultOriginValue, Matrix defaultDestinationValue, AnimationClock animationClock)
{
if (animationClock.CurrentProgress == null)
{
return Matrix.Identity;
}

var normalizedTime = animationClock.CurrentProgress.Value;
if (EasingFunction != null)
{
normalizedTime = EasingFunction.Ease(normalizedTime);
}

var from = From ?? defaultOriginValue;
var to = To ?? defaultDestinationValue;

var newMatrix = new Matrix(
((to.M11 - from.M11) * normalizedTime) + from.M11,
((to.M12 - from.M12) * normalizedTime) + from.M12,
((to.M21 - from.M21) * normalizedTime) + from.M21,
((to.M22 - from.M22) * normalizedTime) + from.M22,
((to.OffsetX - from.OffsetX) * normalizedTime) + from.OffsetX,
((to.OffsetY - from.OffsetY) * normalizedTime) + from.OffsetY);

return newMatrix;
}
}

The code is actually quite simple. The class is derived from the abstract MatrixAnimationBase class. Firstly, three dependency properties are defined, namely From, To and EasingFunction. Next comes a bunch of useful constructors. The interesting part resides in the GetCurrentValueCore method. At first, the current animation time is retrieved. Also, the animation time is eased with the easing function if it is available. Lastly, new matrix is calculated based on the From and To values. Each matrix cell is linearly scaled with the time value. And that’s it! This provides smooth animation for the matrix type!