Exploring MEF Extensibility Points

Managed Extensibility Framework (MEF), Design Patterns, Dependency Injection, .NET 3.5 3 Comments

After I had a chance to dance with MEF, I wanted to go a step further and create my own logic to Bind the dependencies, and integrate it to the existing composition system. I have to say that, oh god, it was NOT as easy that as I expected. Current nature of the APIs  heavily depend  on counter intuitive usage. Again, I am having a difficult time to save my critics as a separate post as you can see :)

There are currently 2 main extensibility points in MEF. Custom Binders and Value Resolvers.

Custom Binders

The current nature of the Composition Container is, basically, Container is the god. It needs to have everything to bind, if you want to add a type binding logic, you are welcome. But first, you need to add your type to the container. Well, that’s a fair game, since our logic is Binding(wiring really) logic - not a type or instance management one. This means that we have to write the following as usual:

   1: CompositionContainer container = new CompositionContainer();
   2: container.AddComponent<Consumer>(consumer);
   3: container.AddComponent<Provider>(provider);
   4: container.Bind();

Where Provider and Consumer are just defined with Export & Import model as MEF needs them :

   1: public class Consumer
   2: {
   3:     [Import(typeof(IProvider))]
   4:     public IProvider Provider
   5:     {
   6:         get;
   7:         set;
   8:     }
   9:
  10:     public Consumer()
  11:     {
  12:
  13:     }
  14:
  15:     public int GetAnInteger()
  16:     {
  17:         return this.Provider.GetAnInteger();
  18:     }
  19:
  20: }

And hence is the provider:

   1: [Export(typeof(IProvider))]
   2: public class FavoredProvider : IProvider
   3: {
   4:     #region IProvider Members
   5:
   6:     public int GetAnInteger()
   7:     {
   8:         return 5;
   9:     }
  10:
  11:     #endregion
  12: }

And this makes the following test to pass, which just expects the hard coded “5″ value to be returned:

   1: /// <summary>
   2: ///A test for GetAnInteger
   3: ///</summary>
   4: [TestMethod()]
   5: public void GetAnIntegerTest()
   6: {
   7:        Consumer target = new Consumer();
   8:        CompositionHelper.InitializeContainerForConsumer(target); // this is where container configuration goes
   9:        int expected = 5;
  10:        int actual;
  11:        actual = target.GetAnInteger();
  12:        Assert.AreEqual(expected, actual);
  13: }}

Now, let’s come up with a hypothetical scenario : We need the same instance for every consumer (singleton). How hypothetical that is for a DI container! So  while configuring I would expect to write something close to the following, and still expect test to pass! (Note that you can use IsSingleton for the contract, but the one and only life time controlling mechanism isn’t singleton is it? ;) )

   1: CompositionContainer container = new CompositionContainer();
   2: var myVeryCustomBinder = new SampleBinder();
   3: container.AddComponent<Consumer>(consumer);
   4: // not adding the provider exlusively, expecting the binder to handle
   5: container.AddBinder(myVeryCustomBinder);
   6: container.Bind();

Q: So we didn’t add the provider to the container, haven’t you just said that this is a deal breaker ?

A: Yes it is, you are right. My test now breaks. But I can make that up, in my custom binder. Gimme a break.

To write a custom binder I need to inherit from the abstract class ComponentBinder . In ComponentBinder, there are several virtual methods that are waiting to be overridden depending on my logic:

  1. public override CompositionResult Export() : This is the place that we’ll add the container the results of our resolve operations. The return value also indicates whether the operation is succeeded or not.
  2. public override CompositionResult Import(IEnumerable<string> changedValueNames) : And this is the place that we will retrieve the demanding objects for the services that are exported.
  3. public override CompositionResult BindCompleted() : This kind of acts as an event, (why is it not one?) and will be called when the binding is completed. Here you can do your sanity checks after your bind operations needed for your binder,
  4. public override IEnumerable<string> ExportNames ; These are the “names” for the types. This can be the name specified in the Export() declaration in the attribute or a default one.
  5. public override IEnumerable<string> ImportNames : Same goes with imports, but instead import process.

So here would be my Custom Binder:

   1: public class SampleBinder : ComponentBinder
   2: {
   3:     private FavoredProvider ProviderToInject
   4:     {
   5:         get;
   6:         set;
   7:     }
   8:
   9:     private static readonly object syncRoot = new object();
  10:
  11:     public SampleBinder()
  12:     {
  13:         if (ProviderToInject == null)
  14:         {
  15:             lock (syncRoot)
  16:             {
  17:                 ProviderToInject = new FavoredProvider();
  18:             }
  19:         }
  20:     }
  21:
  22:     public override CompositionResult Export()
  23:     {
  24:
  25:         this.AddValueToContainer(CompositionServices.GetContractName(typeof(IProvider)), this.ProviderToInject, “Provider”);
  26:         return CompositionResult.SucceededResult; ;
  27:     }
  28:
  29:     public override CompositionResult Import(System.Collections.Generic.IEnumerable<string> changedValueNames)
  30:     {
  31:         return base.Import(changedValueNames);
  32:     }
  33:
  34:     public override CompositionResult BindCompleted()
  35:     {
  36:         return base.BindCompleted();
  37:     }
  38:
  39:     public override IEnumerable<string> ExportNames
  40:     {
  41:         get
  42:         {
  43:             return base.ExportNames;
  44:         }
  45:     }
  46:
  47:     public override IEnumerable<string> ImportNames
  48:     {
  49:         get
  50:         {
  51:             return base.ImportNames;
  52:         }
  53:     }
  54:
  55: }

As you see, we are not doing anything on import. For any import of I provider type, we Are providing  the Favored Provider.  Also notice the badly named utility class CompositionServices which currently only has 1 method, and it is a useful one : GetContractName. Without this, I’d have to hardcode it or get it with a drop of reflection magic.

Adding this Binder Makes my test pass, and I am happy.

Value Resolvers

This is an enabled model in this CTP, but the Usage of it is not enabled (at least I couldnt find out a way, since the Resolver value in the container does not have a setter - any feedback on this appreciated(1)) . Value Resolver is the part to provide the types, and probably in a sane implementation life time logic will go here. It is an abstract class and 2 abstract methods are waiting to be overriden, below is a sample Value Resolver:

   1: public class CustomValueResolver : ValueResolver
   2: {
   3:     public override CompositionResult<IImportInfo>
   4: TryResolveToValue(string name, IEnumerable<string> requiredMetadata)
   5:     {
   6:         // do your resolve, and send it back   
   7:         ImportInfo<FavoredProvider> resolvedValue =
   8:             new ImportInfo<FavoredProvider>(null);
   9:         return new CompositionResult<IImportInfo>(true,
  10:             Enumerable.Empty<CompositionIssue>(), resolvedValue);
  11:     }
  12:
  13:     public override CompositionResult<ImportInfoCollection>
  14: TryResolveToValues(string name, IEnumerable<string> requiredMetadata)
  15:     {
  16:     // do the same if you have more than one service to provide to one consumer
  17:         ImportInfo<FavoredProvider> resolvedValue =
  18:             new ImportInfo<FavoredProvider>(null);
  19:
  20:         return new CompositionResult<IImportInfo>(true,
  21:             Enumerable.Empty<CompositionIssue>(), resolvedValue);
  22:     }
  23: }

In the future hopefully we will be able to create our own component catalogs and associate resolvers to them, like the way we can’t to now to both Container and to AssemblyComponentCatalog.(2)

Hope this article gave a deeper hint on what’s going on MEF side of things. Any comments on this are welcome as always.

 (1): Jason pointed out that there is an overload of CompositionContainer, that takes ValueResolver as a parameter. doh!

(2): Still couldnt find a way of doing the same to Component Catalog.

kick it on DotNetKicks.com

Share it on: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • Blogosphere News
  • e-mail
  • YahooMyWeb
  • DotNetKicks
  • DZone

Managed Extensibility Framework (MEF) at a Glance

Unit Testing, Managed Extensibility Framework (MEF), Design Patterns, Dependency Injection, .NET 3.5 3 Comments

After Krysztof Cwalina has announced Microsoft’s plans on releasing extensible features to .NET framework, the CTP of MEF has made its way too quick into the market. As a result of this, we have an immature .DLL called ComponentModel.dll born into our hands, with being far from complementing the community’s needs and lacking lots of features & architectural concerns – and of course you know it, with nearly no xml comments and not very informative error messages.

But it is still CTP, and that’s what a CTP is for. Criticism against it is a matter of another post; but as .NETters we need to know about this vibe coming because this young baby is going to be a part of the core framework and one day, with an update, will be pushed to x million of computers.

So I better stop judging for the time being and let’s get our hands dirty with what we have currently as early adopters.

Dependency Injection with Management Extensibility Framework

In the dll, there are 2 main namespaces coming: System.ComponentModel.Composition and System.Reflection.StructuredValues . So as you see, to do its magic MEF uses reflection. This also means that one can define contracts using hard coded strings instead of a strongly typed contract. In the examples those are shipped with MEF, you can see this usage, but I think everybody will agree that this is not a good practice. So let’s see how we can build a strongly typed and contract based dependency injection mechanism.

So let’s get to define a very simple contract:

   1: /// <summary>
   2: /// Contract for retrieving pretty dummy data
   3: /// </summary>
   4: public interface IDataRetriever
   5: {
   6:     /// <summary>
   7:     /// Gets the sample data.
   8:     /// </summary>
   9:     /// <param name=”count”>The count.</param>
  10:     /// <returns></returns>
  11:     IEnumerable<ExampleData> GetSampleData(int count);
  12: }

This expects to get a list of example data #count times. ExampleData is a Poco, and its structure contains just a string key:

   1: /// <summary>
   2: /// Model for Sample Data
   3: /// </summary>
   4: public class ExampleData
   5: {
   6:     /// <summary>
   7:     /// Gets or sets the data key.
   8:     /// </summary>
   9:     /// <value>The data key.</value>
  10:     public string DataKey
  11:     {
  12:         get;
  13:         set;
  14:     }
  15: }

So we expect from this method to return a list of ExampleData , with their DataKey field populated by their indexes. So here is the test that ensures this basic expectation:

   1: /// <summary>
   2: ///A test for GetSampleData
   3: ///</summary>
   4: [TestMethod()]
   5: public void GetSampleDataTest()
   6: {
   7:     IDataRetriever target = new DataRetriever();
   8:     int expectedCount, count;
   9:     expectedCount = count = 10;
  10:
  11:     IEnumerable<ExampleData> actual = target.GetSampleData(count);
  12:     Assert.AreEqual(expectedCount, actual.Count<ExampleData>());
  13:
  14:     IEnumerator<ExampleData> enumerator = actual.GetEnumerator();
  15:     int expectedKey = 0;
  16:     while (enumerator.MoveNext())
  17:     {
  18:         Assert.IsNotNull(enumerator.Current);
  19:         Assert.AreEqual(enumerator.Current.DataKey, expectedKey.ToString());
  20:         expectedKey++;
  21:     }
  22: }

And after a couple of failures (yes, even in this simplicity I manage to fail), here is the implementation that passes this test:

   1: [Export(typeof(IDataRetriever))]
   2: public class DataRetriever : IDataRetriever
   3: {
   4:     #region IDataRetriever Members
   5:
   6:     //[Export(”Retriever”)]
   7:     public IEnumerable<ExampleData> GetSampleData(int count)
   8:     {
   9:         List<ExampleData> retVal = new List<ExampleData>(count);
  10:         for (int i = 0; i < count; i++)
  11:         {
  12:             yield return new ExampleData()
  13:             {
  14:                  DataKey = i.ToString()
  15:             };
  16:         }
  17:     }
  18:
  19:     #endregion
  20: }

Now, the syntax of MEF needs us to shout what we have, and explicitly define by attributes what we want to expose as our services to be injected (intrusive, girrrr…) And since there is an exporter, there should be an importer too, which is a page in this scenario. Beware, the page is using this interface and it is marked as public, as MEF can inject only public dependencies choosing the same way as the many of the other IOC containers in the wild.

   1: [Import(typeof(IDataRetriever), IsOptional = false)]
   2: public IDataRetriever Retriever
   3: {
   4:   get;
   5:   set;
   6: }

Note that these Import and Export attributes are under System.ComponentModel.Composition namespace and they both have another overload that takes strings as contract names instead of contract types as shown above.

Please also note that as a client to DataRetriever, this page doesn’t know any bit about which implementation of IDataRetriever that it will retrieve (DI mission accomplished). So in which house is all the party happening? I placed an initialization code inside the page constructor:

   1: public _Default()
   2: {
   3:     DataRetrieverHelper.InitializeContainer<_Default>(this);
   4: }

And this helper is a very smart guy who knows about everything about this magic (so from what we learnt from Italian mafia movies, it should be killed – by a DSL or an XML configuration. But MEF doesn’t support it currently out of the box – but with a bit of a hack it can be done):

   1: public static class DataRetrieverHelper
   2: {
   3:     public static void InitializeContainer<T>(T toFillDependency)
   4:         where T:class
   5:     {
   6:         CompositionContainer container = new CompositionContainer();
   7:         container.AddComponent<T>(toFillDependency);
   8:         container.AddComponent<DataRetriever>(new DataRetriever());
   9:         container.Bind();
  10:     }
  11: }

As you see, you add the consumer, add the service, and call bind – MEF container cares the rest.

Of course, the first question that is expected after how, is what if we need to add another implementation which is a very likely scenario? For e.g what if we have 2 implementations of the contract, say to return a list of keys in reverse order and the normal one, which one is the container going to choose to bind?

Handling Multiple Exports Within the Container

Well, since the requirements are extended, we need to write another test for the new requirement:

To pass this test, the implementation is trivial:

   1: /// <summary>
   2: ///A test for GetSampleData
   3: ///</summary>
   4: [TestMethod()]
   5: public void GetSampleDataReverseTest()
   6: {
   7:     IDataRetriever target = new DataRetreiverReverse();
   8:
   9:     int expectedCount, count;
  10:     expectedCount = count = 10;
  11:
  12:     IEnumerable<ExampleData> actual = target.GetSampleData(count);
  13:     Assert.AreEqual(expectedCount, actual.Count<ExampleData>());
  14:
  15:     IEnumerator<ExampleData> enumerator = actual.GetEnumerator();
  16:     int expectedKey = count - 1;
  17:     while (enumerator.MoveNext())
  18:     {
  19:         Assert.IsNotNull(enumerator.Current);
  20:         Assert.AreEqual(enumerator.Current.DataKey, expectedKey.ToString());
  21:         expectedKey–;
  22:     }
  23: }

It is obvious that if we don’t change the helper class which does the magic, we won’t get the new implementation. So let’s add it by using AddComponent generic method :

   1: public static void InitializeContainer<T>(T toFillDependency)
   2:     where T:class
   3: {
   4:     CompositionContainer container = new CompositionContainer();
   5:     container.AddComponent<T>(toFillDependency);
   6:     container.AddComponent<DataRetriever>(new DataRetriever());
   7:     container.AddComponent<DataRetreiverReverse>(new DataRetreiverReverse());
   8:     container.Bind();
   9: }

Ok, let’s run the application, and face a very nice error message:

“There was at least one composition issue of severity level ‘error’. Review the Issues collection for detailed information”

“WTF is issues collection?” were the first words out of my mouth unfortunately :) . The exception we get here is a System.ComponentModel.Composition.CompositionException and the “issues” is the Issues property of the exception we are getting. This is a collection of System.ComponentModel.Composition.CompositionIssue object, and their Description field is a string that has the meaningful explanation of what’s happening. In the list I got there was 2 issues that we were already expecting:

  1. “Multiple exports were found for contract name ‘MEFSample.Interfaces.IDataRetriever’. The import for this contract requires a single export only.”
  2. “A failure occurred while trying to satisfy member ‘Retriever’ on type ‘default_aspx’ while trying to import value ‘MEFSample.Interfaces.IDataRetriever’. Please review previous issues for details about the failure.”

Apart from not getting the exceptions in the first go, and ignoring the first message is cryptic, well, this is nice. Theoretically I can see all the errors happened during the build up process, not get stuck in the first one.

Back to the game, now I have 2 implementations in the container, I need a mechanism to choose between two – There is where this System.ComponentModel.Composition.ImportInfoCollection comes into the game. This collection holds a list of ImportInfo objects, which are basically information about the injected members, nothing more. Now, the new property will go as follows:

   1: [Import(typeof(IDataRetriever), IsOptional = false)]
   2: public ImportInfoCollection<IDataRetriever> ResolvedDependencies
   3: {
   4:     get;
   5:     set;
   6: }

When “Bind” is called, this property will be filled automatically instead of the old one. So now I have a list, I am able to decide between the resolved dependencies. Here is my new Retriever property:

   1: public IDataRetriever Retriever
   2: {
   3:    get
   4:    {
   5:        return ResolvedDependencies[0].GetBoundValue();
   6:    }
   7: }

Here I am choosing the first one; I can choose the 2nd one as well since Resolved Dependencies collection will have 2 values.Okay, [0] seems a cumbersome way of selecting the “correct” one, admitted :). Frankly, MEF team included the mechanism in this CTP so we can also specify metadata information along with the injected interfaces, which will help us to be able to decide better what implementation to choose in the run time. But this post got long so I hopefully throw another post to explore what we can do within MEF boundaries.

You can download the sources by clicking here.

kick it on DotNetKicks.com

Share it on: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • Blogosphere News
  • e-mail
  • YahooMyWeb
  • DotNetKicks
  • DZone

Linq to SQL Wish List

SQL, .NET 3.5, LINQ 15 Comments

As we are not Microsoft marketers, we tend to see the cons of the products that Microsoft builds. As every product has its flaws, of course Linq to SQL is no exception. Here is my list of the things that I compiled from various sites & forums or hit a limitation block by myself:

A) Architecture

1 – Enabled Provider Model & More providers than SQL

Since Matt Warren has explained in his blog post that LINQ to SQL supported multiple providers internally, but it was disabled for some “non-technical” reasons there is an unstoppable desire in each of us to see it enabled in the next version. (I am not even asking for Persistance Ignorance)

2 – Fully Mockable, A Design by Contract Framework

If this happened, we wouldn’t look for hacks like this one. I want to be able to mock DataContext out without doing any funky tweaks.

3 – A Disconnected Data Context

I can not remember how many times I have seen this everywhere. This DataContext will be able to be serialized & deserialized somewhere and even if it is dead, we should be able to benefit from Object Tracking and Deferred Loading.

By this I mean a stateless DAL, where I don’t have to say “delete these children” or “update these but not these”.

4 – Support for more inheritance models

Currently only Table per Hierarchy model is enabled, multiple entities constituting 1 table or vice versa are not.

5 – Out of the box many to many relationships

Title explains, as we currently can’t do this mapping.

6 – Batch Statements Execution

Currently Linq to SQL sends multiple queries to the DB if an operation needs it. A batch statement like NHibernate’s would have been more than cool.

7 – More control on the resulting statement

Advanced users should be able to sneak in the generation or submission process – like the interceptors in NHibernate again.

B) Tools and Designer

1 – Code generation into different structures

The ability to separate each entity and DataContext into different files or assemblies. Partial files do not let us reside our extensions in different assemblies.

2 – Make DBML designer support giving Entity Base Class

SQL Metal has this, so why does the designer not?

3 – Make DBML designer support external mapping

Again, this is a SQL metal specific “magic”.

4 – Enable partial generation in SQL Metal

Sometimes we human beings do not want to generate all the database, just one table for instance.

This is usually followed by a request on being able to “refresh” an object on the design surface. I don’t know anybody who fancies to delete & drop from connection explorer each time something is changed in the db and loose custom associations.

It would also be good if user changes to designer are kept, not overridden everytime by the tool (a smart merge may be?).

5 – A tool to generate POCO translators from/to Linq Entities

This could be configured in code or via XML files. Some of us (including me) are using Software Factories to generate them; it would have been nice to have an out of the box support in Visual Studio.

That’s all I can remember of at the midnight. What would you like to have in this list apart from these?

kick it on DotNetKicks.com

Share it on: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook