Geeks With Blogs
Development In a Tesseract Observations and Developmental Experiences

I’ve recently been looking at better ways to combine IoC functionality with MEF composition.  I’ve created a workable solution using just MEF but there is some nasty boilerplate floating around when creating nested containers.

As an example to this issue, the data model contains a set of nested objects in which the Root object holds the MEF CompositionContainer and uses that container to satisfy imports on objects it creates.  At some point in the heirarchy, an object representing a context needs to add new features to a container to be used only in children of the context holding object. Currently, I’m using the code below to establish the nested container, but unfortunately, it is tying my code heavily to MEF through the direct use of the container and Import attributes.

  [Import]
  private CompositionContainer CompositionContainer { get; set; }
  
  private void OnImportsSatisfied()
  {
    // we replace the imported container with a new one in which we are adding 
    // context specific services.
    CompositionContainer = new CompositionContainer(CompositionContainer);
      
    var additionalStuff = new AdditionalStuff();
    var batch = new CompositionBatch();
    batch.AddExportedValue(additionalStuff);
    
    // Items deeper in the context chain are going to import this container
    batch.AddExportedValue(CompositionContainer);
    
    CompositionContainer.Compose(batch);
  }

As a starting point for decoupling this code, I’ve looked into the autofac library which with the version 2 experimental version has some MEF integration support.

The example Nicholas Blumhardt uses the Lazy<T> capabilities of .NET 4, but doesn’t really show the integration with MEF using the Catalog registration services.

By making some modifications to the code in his example, you can really show how the MEF components can be pulled into the autofac container very easily.

the first step is to connect the MEF export attributes to the meta data used by the logger imports.

    public interface ILogAppenderMetadata
    {
        string AppenderName { get; }
    }

    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class)]
    public class LogAppenderAttribute : ExportAttribute, ILogAppenderMetadata
    {
        public LogAppenderAttribute() : base(typeof(ILogAppender))
        {
        }

        public string AppenderName { get; set; }
    }

The creation of this attribute will simplify the tagging of exports using the ILogAppender contract. The next step is to apply the new attribute to the logger implementations.

 

 [LogAppender(AppenderName="printer")]
 public class PrinterLogAppender : ILogAppender
  {
  ...
  }
  
  [LogAppender(AppenderName="screen")]
  public class ScreenLogAppender : ILogAppender
  {
  ...
  }

Finally, the Main method is modified to make use of the catalog registration services provided by autofac.

 

  static void Main(string[] args)
  {
    var builder = new ContainerBuilder();
    var catalog = new TypeCatalog(typeof (PrinterLogAppender), typeof (ScreenLogAppender));
    builder.RegisterComposablePartCatalog(catalog);
  
    builder.RegisterType<Program>();
    builder.RegisterType<Log>();
  
    using (var container = builder.Build())
    {
        container.Resolve<Program>().Run();
    }
  }

When the program is run, the container correctly picks up the MEF exports without any further reference to imports and exports.  What I need now is to understand a better way to create the nested containers using the autofac library rather than pure MEF.

Posted on Friday, February 12, 2010 2:33 PM MEF | Back to top

Related Posts on Geeks With Blogs Matching Categories

Comments on this post: Using MEF Exports with Autofac 2

Comments are closed.
Comments have been closed on this topic.
Copyright © Steven Mitcham | Powered by: GeeksWithBlogs.net