Showing posts with label MefContrib. Show all posts
Showing posts with label MefContrib. Show all posts

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, November 9, 2010

Introduction to InterceptingCatalog – Part I

Managed Extensibility Framework uses the concept of catalogs. A single catalog is responsible for providing access to parts, which are mostly components in the system (ordinary .NET classes). I said mostly because MEF is not limited to operating on types, it also supports method, property and field composition. The catalog is then used by the CompositionContainer to pull parts from it. Out of the box MEF ships with 4 core catalogs, which are meant to discover attributed parts (an attributed part is simply a component which uses attributed programming model for discovery purposes). These catalogs are TypeCatalog, DirectoryCatalog, AssemblyCatalog, and AggregateCatalog. Catalogs serve one other crucial purpose – they are responsible for instantiating parts. The thing is that the underlying infrastructure (aka Reflection Model) responsible for that process is hidden from the developer and it is not possible to attach anything to the creation pipeline. People who just begin their MEF adventure might feel a little disappointed at first, because all of the IoC containers available today provide neat infrastructure for integrating custom build strategies into the creation pipeline. Furthermore, some of them, support interception out of the box (like the Unity container from MS Patterns & Practices).

The InterceptingCatalog, initially written by Glenn Block, has been introduced to fix this gap. It provides a convenient mechanism which allows to intercept values exported via MEF, it allows to chain interceptors together to form custom instance processing pipeline (Chain of Responsibility design pattern). The catalog also enables to create exports on the fly (which is used to provide open-generics support for MEF) and to filter existing exports based on some criteria. The catalog itself has been built around the Decorator pattern – it decorates any ComposablePartCatalog. You can find it in the MefContrib project available at mefcontrib.com.

In this series of posts I am going to discuss all the benefits of using the InterceptingCatalog. In the first part I will focus on intercepting capabilities of the catalog, and in subsequent posts I will cover filtering scenario and show how to enable the open-generics support.

Interception

Let’s begin with a simple example and then build on top of it. Assume we have IStartable interface defined as follows:
public interface IStartable
{
bool IsStarted { get; }

void Start();
}

We want every component, which implements the IStartable interface, have its Start method automatically called by the IoC container as part of the creation process. First, lets investigate the solution on the Unity IoC example. Note that the interception term does not apply to the Unity solution as the Unity fully supports custom build strategies =)

public class MyExtension : UnityContainerExtension
{
protected override void Initialize()
{
Context.Strategies.AddNew<StartableStrategy>(UnityBuildStage.Initialization);
}

public class StartableStrategy : BuilderStrategy
{
public override void PreBuildUp(IBuilderContext context)
{
var instance = context.Existing as IStartable;
if (instance != null)
{
instance.Start();
}
}
}
}

The code is dead simple. We define our own extension named MyExtension, which does nothing more than registering the StartableStrategy during the instance initialization phase. The inner StartableStrategy does all the job - if the instance being created implements IStartable, it calls its Start method. The usage is also pretty straightforward. All we have to do is to add MyExtension to the container!

IUnityContainer container = new UnityContainer();
container.AddNewExtension<MyExtension>();

var foo = container.Resolve<StartableFoo>();
Console.WriteLine(foo.IsStarted); // Prints True

Assuming that the StartableFoo part implements the IStartable interface, it will have its Start method called during the Resolve method call. Now let's look at how this scenario could be implemented in MEF. As I stated previously, MEF doesn't allow the developer to register custom build strategies within the build process. Hence, we need to use interception. This is where the InterceptingCatalog comes to play. To use the InterceptingCatalog, we first need to create proper configuration. The configuration is provided by means of InterceptionConfiguration class:

public class InterceptionConfiguration : IInterceptionConfiguration
{
public InterceptionConfiguration AddInterceptor(IExportedValueInterceptor interceptor);
public InterceptionConfiguration AddHandler(IExportHandler handler);
public InterceptionConfiguration AddInterceptionCriteria(IPartInterceptionCriteria partInterceptionCriteria);
}

In this example we are interested in the AddInterceptor and AddInterceptionCriteria methods which add interceptors to the catalog. The two methods correspond to two interception levels supported by the catalog. The first is the catalog wide interception level. Interceptors registered on this level are applied to all parts available in the decorated catalog. The second level is the per part interception level. Interceptors registered on that level apply only to selected parts, and the developer specifies to which parts the interceptor should be applied by specifying a predicate which accepts ComposablePartDefinition and returns bool. Next example will show this in action. Meanwhile, this is how our StartableStrategy might look like:

public class StartableStrategy : IExportedValueInterceptor
{
public object Intercept(object value)
{
var startable = value as IStartable;
if (startable != null)
{
startable.Start();
}

return value;
}
}

As you can see, all interceptors have to implement the IExportedValueInterceptor interface, which defines single Intercept method. The method gets called as soon as the exported value is requested, and the value itself is passed as the parameter. To demonstrate the usage, we will use two parts, namely IFoo and IBar. The IBar part is defined as follows:

public interface IBar
{
void Foo();
}

[Export(typeof(IBar))]
public class Bar : IBar, IStartable
{
public Bar()
{
Console.WriteLine("Bar()");
}

public bool IsStarted { get; private set; }

public void Start()
{
IsStarted = true;
Console.WriteLine("Bar.Start()");
}

public void Foo()
{
Console.WriteLine("Bar.Foo()");
}
}

The code which uses the StartableStrategy is also very simple.

// Create the catalog which will be intercepted
var catalog = new TypeCatalog(typeof(Bar), typeof(Foo));

// Create interception configuration
var cfg = new InterceptionConfiguration()

// Add catalog wide startable interceptor
.AddInterceptor(new StartableStrategy());

// Create the InterceptingCatalog with above configuration
var interceptingCatalog = new InterceptingCatalog(catalog, cfg);

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

var barPart = container.GetExportedValue<IBar>();

Because the IBar part implements the IStartable interface, it will have its Start method called as part of GetExportedValue call. This example concludes the basics of using InterceptingCatalog. Lets move on to the next interception example which uses Castle.DynamicProxy to create proxies for objects. We will add logging capabilities to the IFoo part. We do not want to log method execution on the IBar part, so we are going to leverage the per part interception. The IFoo part looks identical to the IBar part, except it is decorated with ExportMetadata attribute, which tells the system that we want to log method execution on that part.

public interface IFoo
{
void Bar();
}

[Export(typeof(IFoo))]
[ExportMetadata("Log", true)]
public class Foo : IFoo, IStartable
{
public Foo()
{
Console.WriteLine("Foo()");
}

public bool IsStarted { get; private set; }

public void Bar()
{
Console.WriteLine("Foo.Bar()");
}

public void Start()
{
IsStarted = true;
Console.WriteLine("Foo.Start()");
}
}

Next comes the logging interceptor which implements Castle's IInterceptor interface.

public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("--- LOG: About to invoke [{0}] on [{1}] ---",
invocation.Method.Name,
invocation.InvocationTarget.GetType().Name);

// Invoke the intercepted method
invocation.Proceed();

Console.WriteLine("--- LOG: Invoked [{0}] ---", invocation.Method.Name);
}
}

The interceptor simply prints information to the console before and after a method execution. The code which puts this sample together is almost a copy of the previous bootstrapping code:

var catalog = new TypeCatalog(typeof(Bar), typeof(Foo));

// Create interception configuration
var cfg = new InterceptionConfiguration()

// Add Castle DynamicProxy based logging interceptor for parts
// which we want to be logged
.AddInterceptionCriteria(
new PredicateInterceptionCriteria(
new DynamicProxyInterceptor(new LoggingInterceptor()), def =>
def.ExportDefinitions.First().Metadata.ContainsKey("Log") &&
def.ExportDefinitions.First().Metadata["Log"].Equals(true)));

// Create the InterceptingCatalog with above configuration
var interceptingCatalog = new InterceptingCatalog(catalog, cfg);

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

var barPart = container.GetExportedValue<IBar>();
barPart.Foo();

var fooPart = container.GetExportedValue<IFoo>();
fooPart.Bar();

Because we wanted to apply the logging interceptor on a per part basis, we use the AddInterceptionCriteria method, and pass the PredicateInterceptionCriteria instance. The PredicateInterceptionCriteria object takes any instance implementing the IExportedValueInterceptor interface along with a predicate which is used to determine which parts should be intercepted with the given interceptor. In the above example we intercept all parts declaring Export metadata named Log which equals to True. Note that our logging interceptor is based on Castle.DynamicProxy. To use it with the catalog, we need to wrap it with DynamicProxyInterceptor which implements IExportedValueInterceptor and can take any number of IInterceptor implementations. The sample produces the following output:

Interception


You can see that indeed the logging interceptor has only been applied to the IFoo part. Please note also that the IFoo has actually been intercepted by a chain of two interceptors, the StartableStartegy and the LoggingInterceptor (although the above sample code omits the first one for clarity). This forms a processing pipeline similar to pipelines found in regular IoC containers. This is all about interception in MEF. You can download sample code from my code gallery here. In the next post I will look at filtering capabilities. Stay tuned!

Saturday, October 16, 2010

MEF + Object Factories using Export Provider

MEF is a great composition platform. It is great because the power and flexibility it delivers, and at the same time, the learning curve is low. When it comes to part registration, MEF out of the box supports so called attributed programming model, which allows the discoverability simply by applying Export attributes on the parts we want to make available to the world, and Import attributes on the parts which need to consume other parts. However, using this default programming model, the developer has no way of introducing any build strategies which get executed during part’s creation when a concrete part is requested. This concept, know as Chain of Responsibility design pattern, is implemented by many (if not all) dependency injection containers. Most of them allow the developer to add new actions which are executed as part of object creation. Sadly enough, there’s no such facility in MEF. This implies yet another limitation – lack of support for custom object factories. This means it is always MEF who creates parts’ instances.

Luckily, MEF is extensible. It allows to develop completely new programming models by implementing custom catalogs (like the ConventionCatalog which is a part of MefContrib). It also enables the developers to implement custom export providers, whose role it to provide exports from various sources =) In this post I am going to introduce the FactoryExportProvider which extends MEF by allowing to define object factories.

Introducing Custom Factories

When you want co take control over instance creation in MEF, you basically have two options. Either create part manually and then call ComposeExportedValue method on that part as presented on the following listing

var component = new ExternalComponent2();
container.ComposeExportedValue(component);

or use property export as presented below.

[Export]
public IExternalComponent Component1
{
get
{
return new ExternalComponent3(/* Constructor Initialization */);
}
}

The first solution, however, is not very elegant. It also registers new part as singleton. The second one is better, but still the part will be created only once, and reused across many requests. Also note that in both solutions, a problem arises when it comes to injecting target part’s constructor – we don’t have access to the container so we can’t pull required parts from it. Of course we could get a reference to the container, but doing so only for this purpose will make the code more sloppy.

Meet FactoryExportProvider

The FactoryExportProvider is an elegant solution to the outlined problems. Consider the following sample code:

var provider = new FactoryExportProvider()
.RegisterInstance<IExternalComponent>(ep => new ExternalComponent2())
.Register<IExternalComponent>("part4", ep => new ExternalComponent4(
ep.GetExportedValue<IExternalComponent>(),
ep.GetExportedValue<IMefComponent>()));

var container = new CompositionContainer(anyCatalog, provider);
provider.SourceProvider = container;

You can clearly see two parts being registered, both with the same interface. The first one is registered as a singleton (shared in MEF), but more interestingly, the second is registered as transient (non shared in MEF) and will be created each time the part is requested. As part of the registration process, a factory method should be passed (this is not required, read on to find out why) which is responsible for delivering instances. Note also an elegant, though widely adapted, solution to resolving complex constructors. In the example, the ExternalComponent4 has a dependency on IExternalComponent and IMefComponent parts. However, thanks to the fact that the resolution method has access to the source provider (ExportProvider instance), we can use it to satisfy additional imports. Just remember to set SourceProvider property of the FactoryExportProvider to something meaningful (at least to the FactoryExportProvider instance itself as the SourceProvider is null by default). More common is to set it to the CompositionContainer instance.

FactoryExportProvider is quite flexible. It allows to register a fallback factory method which gets executed whenever part is registered without supplying the factory method enabling to design single resolution method for a subset or all parts registered in the factory. See the following example.

private static object FactoryMethod1(Type type, string registrationName)
{
if (type == typeof(IExternalComponent) && registrationName == null)
return new ExternalComponent1();

if (type == typeof(IExternalComponent) && registrationName == "external2")
return new ExternalComponent2();

return null;
}

var provider = new FactoryExportProvider(FactoryMethod1);
var container = new CompositionContainer(someCatalog, provider);

// Registration
provider.Register(typeof(IExternalComponent));
provider.Register(typeof(IExternalComponent), "external2");

The code presented in this post is available as part of MefContrib Project. Latest version is available on my fork. In the coming days I will push it to the main repo though! This export provider is also used by IoC plumbing infrastructure, which is also part of MefContrib Project, which enables integration of IoC and MEF. I blogged about particular implementations for Unity container here and here.

Hope you like it!