Thursday, July 9, 2009

Downloadable videos of the NDC09 sessions

Most of the recorded sessions from the Norwegian Developers Conference 2009 can now be downloaded from Rune Grothaug (Microsoft Developer Community Manager in Norway) blog. The entire conference was awesome and there’s plenty of great material to watch!

The following speakers can be found in the downloadable contents

 

  • Ayende Rahien
  • Craig Larman
  • Ian Griffiths
  • Jeremy D. Miller
  • Jimmy Nilsson
  • Jonas Follesø
  • Kevlin Henney
  • Michael Feathers
  • Michele Leroux Bustamante
  • Mike Cohn
  • Peter Provost
  • Phil Haack
  • Rafal Lukawiecki
  • Richard Campbell
  • Robert C. Martin
  • Roy Osherove
  • Scott Hanselman
  • Ted Neward
  • Tim Huckaby
  • Udi Dahan

So what are you waiting for? Go download the videos now!

Thursday, July 2, 2009

Integrating WCF with your favorite IoC

A while back I was working on a project where I had to implement a Windows Communication Service for authenticating users. Internally the service was going to use a user repository to validate the provided credentials. I wanted to design the service in such a way that it didn't take a hard dependency on a specific user repository implementation, instead I wanted to make use of the Dependency Inversion Principle to decouple the service's dependency on the user repository.


The following code snippet is a scaffold for the authentication service.


[ServiceContract] 
public interface IAuthenticationService
{
[OperationContract]
bool Authenticate(string username, string password);
}

public class AuthenticationService : IAuthenticationService
{
/// <summary>
/// Initializes a new instance of the <see cref=”AuthenticationService” />
/// class, using the specified <see cref=”IUserRepository” /> instance.
/// </summary>
public AuthenticationService(IUserRepository repository)
{
}

public bool Authenticate(string username, string password)
{
// Validate the input and call the user repository to perform the
// authentication.
}
}

The thing to pay attention to in the code above is the introduction of the non-default constructor. This constructor accepts an instance of a class which implements the IUserRepository interface, making the user repository a loose dependency of the service.


Now, if you think about it for a moment you realize that when you invoke a service, an instance of the service is magically created for you. There is no need to explicitly create the instance in order to be able to consume the request. However, in order to be able to decouple the dependency from the service and instead pass it into the service, you need to gain control over the creation of the service instance.


Thankfully the people on the Windows Communication Framework team decided not to keep the creation of the service instance to themselves, but instead make use of the Factory Method pattern. This provides the necessary extensibility point to take control over how the service instance is created.

The factory

You create a custom service factory by deriving from the ServiceHostFactoryBase class and provide the necessary implementation. This can be a bit tedious so fortunately most of the popular inversion of control containers already ship with custom factory implementations, which use the container to resolve dependencies.


I will be using Autofac in my sample, since it’s the inversion of control container of my choice. However if you are looking at doing this using a different container, then you might want to check out the solutions for Castle Windsor, StructureMap, Spring.NET, Unity or Ninject.


The first thing you will need to do is tell the Windows Communication Framework what factory you wish to use when it creates an instance of the service. You do this by editing the .svc file and add the Factory attribute.


When using Autofac you would do the following


<%@ 
Service="TheCodeJunkie.Wcf.AuthenticationService, TheCodeJunkie.Wcf"
CodeBehind="AuthenticationService.svc.cs"
Factory="Autofac.Integration.Wcf.AutofacWebServiceHostFactory, Autofac.Integration.Wcf"
%>

Make sure you have a reference to the Autofac.Integration.Wcf assembly or it is going to fail horribly when you try to call your service, because it won't be able to resolve the type of the factory.


Next you have to make sure that the type specified in the Service attribute is the Assembly Qualified Name of the type. By default the assembly part is not included in this attribute and without it the Autofac factory will be unable to locate the type of the service. Note that if you are using a different IoC or factory implementation, this might not be a required step.


Depending on what type of service you are building, you are going to want to use different Autofac factories to give you the desired functionality. If you are building SOAP services you should use the AutofacServiceHostFactory, but if you are building a REST service you should use the AutofacWebServiceHostFactory.

Configuring the service host

Once the service has been prepared, the container needs to be setup and registered with the factory so that it can pull the service instances out of it. The container is setup just like for any other dependency, but you also tell the factory which container it should be use to resolve the dependencies a service might have.


var builder = 
new ContainerBuilder();

builder
.Register<FakeUserRepository>()
.As<IUserRepository>()
.SingletonScoped();

builder
.Register<AuthenticationService>()
.As<IAuthenticationService>()
.FactoryScoped();

AutofacWebServiceHostFactory.Container = builder.Build();

The Autofac factories have the common Container property, which is a static property. It only has to be set once even though you are hosting many different types of services. This also means that the SOAP and REST factory share the same container.

Conclusion

By following the Dependency Inversion Principle you can create services with loosely coupled dependencies, with only a few lines of code. This is possibly thanks to the fact that Microsoft decided to give you the option to control how a service instance is manufactured. It is also because of the rich support for WCF integration by the popular Inversion of Control containers.


Loose coupling enables you to make modifications to the behavior and capabilities of your application without having to rewrite it (see Open / Closed Principle). It also promotes writing maintainable and reusable code, as well enabling convenient unit testing.


Shout it kick it on DotNetKicks.com

Thursday, May 14, 2009

An introduction to MEF programming models

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


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


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


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


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

Programming models

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


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

 

image

 

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


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


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

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

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


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

Creating a custom programming model

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


These classes are collectively known as the Composition Primitives

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

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


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


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

The provider model

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


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


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


Definition Providers

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

 

image

 

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


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

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

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

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

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

var provider =
new ConfigurableDefinitionProvider("mef.configuration");

var catalog =
new DefinitionProviderPartCatalog<ConfigurableDefinitionProvider>(provider);

var batch =
new CompositionBatch();
batch.AddProviderPart(this);

var container =
new CompositionContainer(catalog);
container.Compose(batch);

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

provider
.Import<Program>(p => p.Service)
.WithContract(typeof(IMessageService))
.Export<NullMessageService>(n => n)
.WithContract(typeof(IMessageService));

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

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


Object Factories

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


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

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

object proxy =
engine.CreateProxy(type, parameters);

return proxy;
}
}

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

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

catalog.Factory = new NAspectObjectFactory();

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


Trusted Assemblies & Configuration

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


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

provider
.Import<Program>(p => p.Service)
.WithContract(typeof(IMessageService))
.Export<NullMessageService>(n => n)
.WithContract(typeof(IMessageService));

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

catalog.Configuration
.Trust(Assembly.GetExecutingAssembly())
.Trust(AppDomain.Current)
.Trust("some-public-key");

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


The Future

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


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


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



Shout it

Tuesday, March 24, 2009

Using a custom container to add default value support to MEF

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


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


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


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


[Test]
public void DefaultValueShouldBeUsedIfNoMatchingExportsAreFound()
{
ContractBasedImportDefinition definition =
new ContractBasedImportDefinition(
"MessageService",
ImportCardinality.ZeroOrOne,
true,
false);

var defaultMessageService =
new DefaultMessageService();

var container =
new DefaultValueContainer();

container
.Register("MessageService")
.With(defaultMessageService);

var results =
container.GetExports(definition);

Assert.IsTrue(results.Count() == 1);
Assert.IsTrue(results.First().GetExportedObject().GetType() == typeof(DefaultMessageService));
Assert.AreSame(results.First().GetExportedObject(), defaultMessageService);
}

[Test]
public void DefaultValuesShouldNotBeUsedIfMatchingExportsAreFound()
{
FakeExportProvider provider =
new FakeExportProvider();
provider.AddExport("MessageService", new SmtpMessageService());

ContractBasedImportDefinition definition =
new ContractBasedImportDefinition(
"MessageService",
ImportCardinality.ZeroOrOne,
true,
false);

var defaultMessageService =
new DefaultMessageService();

var container =
new DefaultValueContainer(provider);

container
.Register("MessageService")
.With(defaultMessageService);

var results =
container.GetExports(definition);

Assert.IsTrue(results.Count() == 1);
Assert.IsTrue(results.First().GetExportedObject().GetType() == typeof(SmtpMessageService));
}

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


Implementing the container

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


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

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


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

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


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


/// <summary>
/// Initializes a new instance of the <see cref="DefaultValueContainer"/> class.
/// </summary>
public DefaultValueContainer()
: this((ComposablePartCatalog)null)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="DefaultValueContainer"/> class, using
/// the provided list of <see cref="ExportProvider"/> instances.
/// </summary>
/// <param name="providers">A list of <see cref="ExportProvider"/> instances.</param>
public DefaultValueContainer(params ExportProvider[] providers)
: this(null, providers)
{
}

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

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


/// <summary>
/// Gets a list of <see cref="Export"/> objects which matches the provided <see cref="ImportDefinition"/>.
/// </summary>
/// <param name="definition">The <see cref="ImportDefinition"/> to get the exports for.</param>
/// <returns>An <see cref="IEnumerable{T}"/> object.</returns>
protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition)
{
var exports =
this.TryGetExportsCore(definition);

if (exports.Count() == 0)
{
var contractDefinition =
definition as ContractBasedImportDefinition;

if (contractDefinition != null)
{
string contractName =
contractDefinition.ContractName;

if (this.Defaults.ContainsKey(contractName))
{
return this.Defaults[contractName];
}
}
}

return exports;
}

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


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

return Enumerable.Empty<Export>();
}

Adding the fluent interface for manipulating default values

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


/// <summary>
/// Registers a contract so that default values can be assigned.
/// </summary>
/// <param name="contractName">Then name of the contract to register default values for.</param>
/// <returns>The current <see cref="DefaultValueContainer"/> object.</returns>
/// <exception cref="ArgumentException">The provided value of the <paramref name="contractName"/> parameter was <see langword="null"/> or empty.</exception>
public DefaultValueContainer Register(string contractName)
{
if (string.IsNullOrEmpty(contractName))
{
throw new ArgumentException("The name of the contract cannot be null or empty.");
}

if (!this.Defaults.ContainsKey(contractName))
{
this.Defaults.Add(contractName, new Collection<Export>());
}

return this;
}

/// <summary>
/// Registers a <see cref="Type"/> as a contract so that default values can be assigned.
/// </summary>
/// <param name="contractType">The <see cref="Type"/> to register as the contract.</param>
/// <returns>The current <see cref="DefaultValueContainer"/> object.</returns>
/// <remarks>The value of the <see cref="Type.FullName"/> property will be used as the contract.</remarks>
/// <exception cref="ArgumentNullException">The provided value of the <paramref name="contractType"/> parameter was <see langword="null"/>.</exception>
public DefaultValueContainer Register(Type contractType)
{
if (contractType == null)
{
throw new ArgumentNullException("contractType", "The contract type cannot be null.");
}

return this.Register(contractType.FullName);
}

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


/// <summary>
/// Unregisters a contract and removes all previously registered default values assigned to it.
/// </summary>
/// <param name="contractName">The contract to unregister.</param>
/// <returns>The current <see cref="DefaultValueContainer"/> object.</returns>
/// <exception cref="ArgumentException">The provided value of the <paramref name="contractName"/> parameter was <see langword="null"/> or empty.</exception>
public DefaultValueContainer Unregister(string contractName)
{
if (string.IsNullOrEmpty(contractName))
{
throw new ArgumentException("The name of the contract cannot be null or empty.");
}

this.Defaults.Remove(contractName);

return this;
}

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

this.Unregister(contractType.FullName);

return this;
}

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


/// <summary>
/// Adds a default value to the last registered contract.
/// </summary>
/// <param name="defaultValue">The default value to add.</param>
/// <returns>The current <see cref="DefaultValueContainer"/> object.</returns>
/// <exception cref="ArgumentNullException">The provided value of the <paramref name="defaultValue"/> parameter was <see langword="null"/>.</exception>
public DefaultValueContainer With(object defaultValue)
{
if (defaultValue == null)
{
throw new ArgumentNullException("defaultValue", "The default value cannot be null.");
}

Export wrapper =
new Export(this.Defaults.Last().Key, () => defaultValue);

this.Defaults.Last().Value.Add(wrapper);

return this;
}

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

foreach (var defaultValue in defaultValues)
{
this.With(defaultValue);
}

return this;
}

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


How the container could be further extended

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


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


  • Constructor overload for injecting defaults when the container is instantiated

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

  • Being able to unregister individual defaults on a specific contract

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


Finally

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

Shout it

Wednesday, March 18, 2009

Creating a FakeExportProvider to help with testing MEF code

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


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

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

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


/// <summary>
/// Defines an <see cref="ExportProvider"/> which allows you to add object instances as
/// exports for a specific contract. The provider is useful when you need to test MEF
/// code and need control over the available exports.
/// </summary>
public class FakeExportProvider : ExportProvider
{
/// <summary>
/// Initializes a new instance of the <see cref="FakeExportProvider"/> class.
/// </summary>
public FakeExportProvider()
: this(new Dictionary<ExportDefinition, Collection<Export>>())
{
}

/// <summary>
/// Initializes a new instance of the <see cref="FakeExportProvider"/> class, using
/// the provided exports.
/// </summary>
/// <param name="exports">A <see cref="Dictionary{TKey, TValue}"/> object, containing the initial exports.</param>
public FakeExportProvider(Dictionary<ExportDefinition, Collection<Export>> exports)
{
this.Exports = exports;
}

/// <summary>
/// Gets or sets the list of available exports.
/// </summary>
/// <value>A <see cref="Dictionary{TKey, TValue}"/> object.</value>
protected Dictionary<ExportDefinition, Collection<Export>> Exports { get; set; }

/// <summary>
/// Gets a list of <see cref="Export"/> objects which matches the provided <see cref="ImportDefinition"/>.
/// </summary>
/// <param name="definition">The <see cref="ImportDefinition"/> to get the exports for.</param>
/// <returns>An <see cref="IEnumerable{T}"/> object.</returns>
protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition)
{
throw new NotImplementedException();
}
}

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


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


/// <summary>
/// Adds an export with a specified contract name.
/// </summary>
/// <param name="contractName">A <see cref="String"/> containing the name of the contract.</param>
/// <param name="export">The object to add as an export.</param>
public void AddExport(string contractName, object export)
{
var found =
from e in this.Exports
where string.Compare(e.Key.ContractName, contractName, StringComparison.OrdinalIgnoreCase) == 0
select e;

if (found.Count() == 0)
{
ExportDefinition definition =
new ExportDefinition(contractName, new Dictionary<string, object>());

this.Exports.Add(definition, new Collection<Export>());
}

Export wrapper =
new Export(contractName, () => export);

found.First().Value.Add(wrapper);
}

/// <summary>
/// Adds a list of exports with a specified contract name.
/// </summary>
/// <param name="contractName">A <see cref="String"/> containing the name of the contract.</param>
/// <param name="exports">A list of objects to add as exports.</param>
public void AddExports(string contractName, IEnumerable exports)
{
foreach (var export in exports)
{
this.AddExport(contractName, export);
}
}

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


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


/// <summary>
/// Gets a list of <see cref="Export"/> objects which matches the provided <see cref="ImportDefinition"/>.
/// </summary>
/// <param name="definition">The <see cref="ImportDefinition"/> to get the exports for.</param>
/// <returns>An <see cref="IEnumerable{T}"/> object.</returns>
protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition)
{
var contractDefinition =
definition as ContractBasedImportDefinition;

if (contractDefinition != null)
{
string contractName =
contractDefinition.ContractName;

if (!string.IsNullOrEmpty(contractName))
{
var exports =
from e in this.Exports
where string.Compare(e.Key.ContractName, contractName, StringComparison.OrdinalIgnoreCase) == 0
select e.Value;

if (exports.Count() > 0)
{
return exports.First();
}
}
}

return Enumerable.Empty<Export>();
}

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


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


[Test]
public void ContainerShouldReturnInstancesRegisteredForTheContract()
{
FakeExportProvider provider =
new FakeExportProvider();
provider.AddExport("Foo", new DefaultMessageService());

var container =
new CompositionContainer(provider);

ContractBasedImportDefinition definition =
new ContractBasedImportDefinition(
"Foo",
ImportCardinality.ZeroOrOne,
true,
false);

var results =
container.GetExports(definition);

Assert.IsTrue(results.Count() == 1);
Assert.IsTrue(results.First().GetExportedObject().GetType() == typeof(DefaultMessageService));
}

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


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

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


Shout it

Tuesday, March 3, 2009

Adding context awareness to a fluent interface with the decorator pattern

I recently developed and released the first version of my custom programming model for the Managed Extensibility Framework (MEF). One of the things I included in the extension was a Fluent Definition Provider, a fluent interface used describe composable parts in a way that the programming model can consume them. A composable part used, in my extension, is defined with the help of a type name and collections of exports and imports.


The first version of the fluent interface looked similar to the following piece of code

  1: public class FluentDefinitionProvider
  2: {
  3:     public FluentDefinitionProvider()
  4:     {
  5:     }
  6: 
  7:     public FluentDefinitionProvider AddMetadata(string name, object value)
  8:     {
  9:         // Implementation omitted for clarity.
 10:         return this;
 11:     }
 12: 
 13:     public FluentDefinitionProvider AddRequiredMetadata(string name)
 14:     {
 15:         // Implementation omitted for clarity.
 16:         return this;
 17:     }
 18: 
 19:     public FluentDefinitionProvider Export<T>(Expression<Func<T, object>> exportExpression)
 20:     {
 21: 
 22:         // Implementation omitted for clarity.
 23:         return this;
 24:     }
 25: 
 26:     public FluentDefinitionProvider Import<T>(Expression<Func<T, object>> importExpression)
 27:     {
 28:         // Implementation omitted for clarity.
 29:         return this;
 30:     }
 31: 
 32:     public FluentDefinitionProvider WithContract(string contractName)
 33:     {
 34:         // Implementation omitted for clarity.
 35:         return this;
 36:     }
 37: }

At first glance it might look like the interface violates the single responsibility principle because there is no ‘starter method’ for  defining a composable part, only method to define exports and imports, as well as method for altering their state. Looks can be deceiving and without showing you the full implementation of the class it’s impossible to know that internally the provider automatically manages the composable part definitions by inspecting the generic argument of the export and export methods. Also please note that the expression tree parameters or the export and import methods are implementation details of the class and it not related to the design of the fluent interface.


Each time the export of import method is called, the provider tries to retrieve a composable part which matches type of the the generic argument and use that as the active composable part. If no match could be found it will create and store one for the type. So in fact the interface does not violate the single responsibility principle, it most definitely is used to define composable part but its been written in a such a way that the consumer doesn’t explicitly have to define the composable part. This also leaves for a nicer user experience since export and imports for a specific type doesn’t have to be declared sequentially if you don’t want to.


The one thing that really annoyed me with this implementation was the fact that the interface contained methods which could be called out of order, for example AddRequireMetadata is only valid on an import and AddMetadata is only valid on an export, resulting in either an exception being thrown or having me write code to detect it and gracefully handle it.


So I decided I wanted to prevent methods from being called out of order, but I really didn’t want to have to include code in each method to make sure it was called in a valid context. I needed a better design of the fluent interface, one that would solve my problem without having to track the state in each method. What I needed was a way to make the fluent interface context aware so when I, for example, was defining an import I would only see the method that applied to an import and the same for an export.


After some thinking I decided I would use the decorator design pattern to solve my problems. The decorator pattern enables you to add (or decorate) a class with more functionality at runtime. Wikipedia lists several possible implementations of the pattern and the one I choose to go with was to create wrappers around my provider. So the FluentDefinitionProvider was rewritten to have an interface similar to


  1: public class FluentDefinitionProvider
  2: {
  3:     public FluentDefinitionProvider()
  4:     {
  5:     }
  6: 
  7:     public ExportDecorator Export<T>(Expression<Func<T, object>> exportExpression)
  8:     {
  9:         var decorator =
 10:             new ExportDecorator(this);
 11:         return decorator.Export<T>(exportExpression);
 12:     }
 13: 
 14:     public ImportDecorator Import<T>(Expression<Func<T, object>> importExpression)
 15:     {
 16:         var decorator =
 17:             new ImportDecorator(this);
 18:         return decorator.Import<T>(importExpression);
 19:     }
 20: }

The most obvious change is the reduction in available methods. The surface of the interface has been reduced to a minimum, which helps with the discoverability and usability. The second thing worth noticing is that the return type of the two method has changed from being of the type FluentDefinitionProvider into ExportDecorator and ImportDecorator. The decorators wrap the FluentDefinitionProvider to expose a specialized view for working with imports and exports.


I should also mention that there is also a public property, on the FluentDefinitionProvider, which is used to expose the available composable parts. For the sake of the context awareness this could just as well have been made internal instead of public, but making is public suited this particular interface.


  1: public class FluentDefinitionProvider
  2: {
  3:     public FluentDefinitionProvider()
  4:     {
  5:     }
  6: 
  7:     public Collection<PartDescription> Descriptions { get; protected set; }
  8: 
  9:     public ExportDecorator Export<T>(Expression<Func<T, object>> exportExpression)
 10:     {
 11:         var decorator =
 12:             new ExportDecorator(this);
 13:         return decorator.Export<T>(exportExpression);
 14:     }
 15: 
 16:     public ImportDecorator Import<T>(Expression<Func<T, object>> importExpression)
 17:     {
 18:         var decorator =
 19:             new ImportDecorator(this);
 20:         return decorator.Import<T>(importExpression);
 21:     }
 22: }

The decorators uses this property to get access to the part and the export/import which is currently in context (basically it uses a Linq extension to get the last part and the last export/import depending on the decorator) so that it’s state can be altered. If you look closely you see that the actual implementations of the export and import method have been moved from the FluentDefinitionProvider into the decorators. This means that the methods on the interface work as starter methods and nothing more, i.e they help you get a hold of the correct context.


There was some functionality which I wanted both of my decorators to share, so I created the Decorator base class and put the shared functionality in that class.


  1: public abstract class Decorator
  2: {
  3:     protected Decorator(FluentDefinitionProvider provider)
  4:     {
  5:         this.Provider = provider;
  6:         this.CurrentPart = this.Provider.Descriptions.Last();
  7:     }
  8: 
  9:     public PartDescription CurrentPart { get; protected set; }
 10: 
 11:     public FluentDefinitionProvider Provider { get; protected set; }
 12: 
 13:     public ExportDecorator Export<T>(Expression<Func<T, object>> exportExpression)
 14:     {
 15:         // Implementation omitted for clarity.
 16: 
 17:         var decorator =
 18:             new ExportDecorator(this.Provider) { CurrentPart = this.GetPart(typeof(T)) };
 19:         decorator.CurrentPart.Exports.Add(description);
 20: 
 21:         return decorator;
 22:     }
 23: 
 24:     public ImportDecorator Import<T>(Expression<Func<T, object>> importExpression)
 25:     {
 26:         // Implementation omitted for clarity.
 27: 
 28:         var decorator =
 29:             new ImportDecorator(this.Provider) { CurrentPart = this.GetPart(typeof(T)) };
 30:         decorator.CurrentPart.Imports.Add(description);
 31: 
 32:         return decorator;
 33:     }
 34: }

Basically the main functionality of the Decorator base class is to provide the implementations of the export and import methods. By having them in the base class, they are shared across the ExportDecorator and ImportDecorator and that enables me to switch context, so for example when I’m done adding an import I can start adding an export (or another import) since that method will always been in context. There are some other small properties to help reduce the amount of code needed in the subclasses and to keep track of the provider instance which is being decorated.


With the base class in place, the ExportDecorator and ImportDecorator classes can be implemented. They are going to provide a context specific view of the provider, i.e only show the method which are valid to call in the specific context the provider currently is in.


Here are partial implementation of the ExportDecorator and ImportDecorator classes.


  1: public class ExportDecorator : Decorator
  2: {
  3:     public ExportDecorator(FluentDefinitionProvider provider)
  4:         : base(provider)
  5:     {
  6:     }
  7: 
  8:     public ExportDecorator AddMetadata(string name, object value)
  9:     {
 10:         this.CurrentPart.Exports.Last().Metadata.Add(name, value);
 11:         return this;
 12:     }
 13: 
 14:     public ExportDecorator WithContract(string contract)
 15:     {
 16:         this.CurrentPart.Exports.Last().Contract = contract;
 17:         return this;
 18:     }
 19: }
 20: 
 21: public class ImportDecorator : Decorator
 22: {
 23:     public ImportDecorator(FluentDefinitionProvider provider)
 24:         : base(provider)
 25:     {
 26:     }
 27: 
 28:     public ImportDecorator AddRequiredMetadata(string name)
 29:     {
 30:         this.CurrentPart.Imports.Last().RequiredMetadata.Add(name);
 31:         return this;
 32:     }
 33: 
 34:     public ImportDecorator AllowDefault(bool allowDefault)
 35:     {
 36:         this.CurrentPart.Imports.Last().AllowDefault = allowDefault;
 37:         return this;
 38:     }
 39:    
 40:     public ImportDecorator WithContract(string contract)
 41:     {
 42:         this.CurrentPart.Imports.Last().Contract = contract;
 43:         return this;
 44:     }
 45: }

And that’s more or less how you can add context awareness to a fluent interface. Each of the decorators exposes a specialized view of the interface. It’s not possible for me to call AddMetadata on an import or AllowDefault on an export, the compiler will tell me I’m not behaving if I try.


There are some other added benefits to this approach. First of all it delivers a very nice intellisense experience and second of all, thanks to the fact that you are working with concrete classes, you open up the possibility to extend the implementation at a later stage with the help of extensions methods!


If you want to take a look at the full implementation of the FluentDefinitionProvider, then visit the MEF Contrib and download the source code release. The class is located under the MefContrib.Models.Provider.Definitions.Fluent namespace.

Thursday, February 19, 2009

Creating a MEF composition container with the ability to filter exports

When I first started exploring the metadata capabilities of MEF, I soon found myself wanting to, not only, restrict what metadata I wanted the exports to have but also the value of the metadata. Early attempts included crude solutions such as importing to a private member, and then having a public member which applied the filtering for me. I didn’t like it then and I don’t like it now. I would force me to write more code and clutter up my classes.


I’ve seen the question of metadata value filtering surface a couple of time on the MEF discussion list and when I came across it the other day I decided to give it another stab. My first solution included writing a custom export provider to filer exports, but this means it would only work to filter out exports which originates from other export providers which I control, since the CompositionContainer class off MEF creates a couple of export providers internally and there’s no way of wrapping them up in a filter.


So the next step was to create a custom composition container which had filter capabilities.

  1: /// <summary>
  2: /// Defines a <see cref="CompositionContainer"/> with the capability of applying a condition on exports
  3: /// which matches any of the registered contracts.
  4: /// </summary>
  5: public class ConditionalCompositionContainer : CompositionContainer
  6: {
  7:     /// <summary>
  8:     /// Initializes a new instance of the <see cref="ConditionalCompositionContainer"/> class, using
  9:     /// the specified <see cref="CompositionContainer"/>.
 10:     /// </summary>
 11:     /// <param name="catalog">The catalog to add to the container.</param>
 12:     public ConditionalCompositionContainer(ComposablePartCatalog catalog)
 13:         : base(catalog)
 14:     {
 15:         this.Filters = new Dictionary<string, Func<Export, bool>>();
 16:     }
 17: 
 18:     /// <summary>
 19:     /// Gets or sets filters which are availble to the container.
 20:     /// </summary>
 21:     /// <value>
 22:     /// A <see cref="IDictionary{TKey,TValue}"/> object. The of the dictionairy should 
 23:     /// be the contract name.
 24:     /// </value>
 25:     protected IDictionary<string, Func<Export, bool>> Filters { get; set; }
 26: 
 27:     /// <summary>
 28:     /// Registers a contract as a filter.
 29:     /// </summary>
 30:     /// <param name="contractName">The name of the contract to register.</param>
 31:     /// <returns>A <see cref="ConditionalCompositionContainer"/> object.</returns>
 32:     public virtual ConditionalCompositionContainer Register(string contractName)
 33:     {
 34:         this.Filters.Add(contractName, null);
 35:         return this;
 36:     }
 37: 
 38:     /// <summary>
 39:     /// Registers a contract as a filter.
 40:     /// </summary>
 41:     /// <param name="contractType">The <see cref="Type"/> of the contract to register.</param>
 42:     /// <returns>A <see cref="ConditionalCompositionContainer"/> object.</returns>
 43:     public virtual ConditionalCompositionContainer Register(Type contractType)
 44:     {
 45:         return this.Register(contractType.Name);
 46:     }
 47: 
 48:     /// <summary>
 49:     /// Assigns a condition to the previously registered contract.
 50:     /// </summary>
 51:     /// <param name="condition">
 52:     /// A <see cref="Func{T,TResult}"/> object containing the condition 
 53:     /// to apply to the contract.
 54:     /// </param>
 55:     /// <returns>A <see cref="ConditionalCompositionContainer"/> object.</returns>
 56:     public virtual ConditionalCompositionContainer Where(Func<Export, bool> condition)
 57:     {
 58:         this.Filters[this.Filters.Last().Key] = condition;
 59:         return this;
 60:     }
 61: 
 62:     /// <summary>
 63:     /// Gets the exports which matches the provided <see cref="ImportDefinition"/>.
 64:     /// </summary>
 65:     /// <param name="definition">The import definition to find exports for.</param>
 66:     /// <returns>A <see cref="IEnumerable{T}"/> object, containing the matched exports.</returns>
 67:     protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition)
 68:     {
 69:         ContractBasedImportDefinition import =
 70:             definition as ContractBasedImportDefinition;
 71: 
 72:         if (import != null)
 73:         {
 74:             Func<Export, bool> condition;
 75:             if (this.Filters.TryGetValue(import.ContractName, out condition))
 76:             {
 77:                 return base.GetExportsCore(definition).Where(condition);
 78:             }
 79:         }
 80: 
 81:         return base.GetExportsCore(definition);
 82:     }
 83: }

This enables you to register conditions on a specific contract, using a lambda expression and a small fluent API. For example you could do something like this

  1: private void Compose()
  2: {
  3:     var catalog =
  4:         new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
  5: 
  6:     var batch =
  7:         new CompositionBatch();
  8:     batch.AddPart(this);
  9: 
 10:     Dictionary<string, object> expectedMetadata =
 11:         new Dictionary<string, object>
 12:             {
 13:                 { "Foo", 10},
 14:                 { "Bar", 1 }
 15:             };
 16: 
 17:     var container =
 18:         new ConditionalCompositionContainer(catalog);
 19: 
 20:     container
 21:         .Register("TestMethod")
 22:         .Where(e => expectedMetadata.All(m => e.Metadata.ContainsKeyWithValue(m.Key, m.Value)));
 23:     
 24:     container.Compose(batch);
 25: }

To restricts exports, with the contract name of TestMethod to only be imported if they contained the metadata names Foo and Bar with the values of 10 and 1. You could take it a step further and make sure that metadata is within a valid value range and so on. The ContainsKeyWithValue method is a simple extension method on IDictionairy


  1: public static class IDictionaryExtensions
  2: {
  3:     public static bool ContainsKeyWithValue(this IDictionary<string, object> dictionary, string key, object value)
  4:     {
  5:         if (dictionary.ContainsKey(key))
  6:         {
  7:             return dictionary[key].Equals(value);
  8:         }
  9: 
 10:         return false;
 11:     }
 12: }

Please keep in mind that the ConditionalCompositionContainer class could do with some more attention before it’s put into production code. Better exception handling is one area which could do with soem improvements before you put it to use.