Claims, MEF, and Parallelization, Oh My

One of the projects I’ve been working on for the last couple months has a requirement to aggregate a set of claims from multiple data sources for an identity and return the collection.  It all seems pretty straightforward as long as you know what the data sources are at development time as well as how you want to transform the data to claims. 

In the real world though, chances are you will need to modify how that transformation happens or modify the data sources in some way.  There are lots of ways this can be accomplished, and I’m going to look at how you can do it with the Managed Extensibility Framework (MEF).

Whenever I think of MEF, this is the best way I can describe how it works:

image

MEF being the magical part.  In actual fact, it is pretty straightforward how the underlying pieces work, but here is the sales bit:

Application requirements change frequently and software is constantly evolving. As a result, such applications often become monolithic making it difficult to add new functionality. The Managed Extensibility Framework (MEF) is a new library in .NET Framework 4 and Silverlight 4 that addresses this problem by simplifying the design of extensible applications and components.

The architecture of it can be explained on the Codeplex site:

MEF_Diagram.png

The composition container is designed to discover ComposablePart’s that have Export attributes, and assign these Parts to an object with an Import attribute.

Think of it this way (this is just one possible way it could work).  Let’s say I have a bunch of classes that are plugins for some system.  I will attach an Export attribute to each of those classes.  Then within the system itself I have a class that manages these plugins.  That class will contain an object that is a collection of the plugin class type, and it will have an attribute of ImportMany.  Within this manager class is some code that will discover the Exported classes, and generate a collection of them instantiated.  You can then iterate through the collection and do something with those plugins.  Some code might help.

First, we need something to tie the Import/Export attributes together.  For a plugin-type situation I prefer to use an interface.

namespace PluginInterfaces
{
    public interface IPlugin
    {
        public string PlugInName { get; set; }
    }
}

Then we need to create a plugin.

using PluginInterfaces;

namespace SomePlugin
{
    class MyAwesomePlugin : IPlugin
    {
        public string PlugInName
        {
            get
            {
                return "Steve is Awesome!";
            }
            set { }
        }
    };
}

Then we need to actually Export the plugin.  Notice the namespace addition.  The namespace can be found in the System.ComponentModel.Composition assembly in .NET 4.

using PluginInterfaces;
using System.ComponentModel.Composition;

namespace SomePlugin
{
    [Export(typeof(IPlugin))]
    class MyAwesomePlugin : IPlugin
    {
        public string PlugInName
        {
            get
            {
                return "Steve is Awesome!";
            }
            set { }
        }
    };
}

The [Export(typeof(IPlugin))] is a way of tying the Export to the Import.

Importing the plugin’s requires a little bit more code.  First we need to create a collection to import into:

[ImportMany(typeof(IPlugin))]
List<IPlugin> plugins = new List<IPlugin>();

Notice the typeof(IPlugin).

Next we need to compose the pieces:

using (DirectoryCatalog catalog = new DirectoryCatalog(pathToPluginDlls))
using (CompositionContainer container = new CompositionContainer(catalog))
{
    container.ComposeParts(this);
}

The ComposeParts() method is looking at the passed object and finds anything with the Import or ImportMany attributes and then looks into the DirectoryCatalog to find any classes with the Export attribute, and then tries to tie everything together based on the typeof(IPlugin).

At this point we should now have a collection of plugins that we could iterate through and do whatever we want with each plugin.

So what does that have to do with Claims?

If you continue down the Claims Model path, eventually you will get tired of having to modify the STS every time you wanted to change what data is returned from the RST (Request for Security Token).  Imagine if you could create a plugin model that all you had to do was create a new plugin for any new data source, or all you had to do was modify the plugins instead of the STS itself.  You could even build a transformation engine similar to Active Directory Federation Services and create a DSL that is executed at runtime.  It would make for simpler deployment, that’s for sure.

And what about Parallelization?

If you have a large collection of plugins, it may be beneficial to run some things in parallel, such as a GetClaims([identity]) type call.

Using the Parallel libraries within .NET 4, you could very easily do something like:

Parallel.ForEach<IPlugin>(plugins, (plugin) =>
{
    plugin.GetClaims(identity);
});

The basic idea for this method is to take a collection, and do an action on each item in the collection, potentially in parallel.   The ForEach method is described as:

ForEach<TSource>(IEnumerable<TSource> source, Action<TSource> action)

When everything is all said and done, you now have a basic parallelized plugin model for your Security Token Service.  Pretty cool, I think.