<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>MEF</title>
        <link>http://geekswithblogs.net/smitcham/category/11240.aspx</link>
        <description>Posts related to developing with Manged Extensions Framework</description>
        <language>en-US</language>
        <copyright>Steven Mitcham</copyright>
        <managingEditor>smitcham@gmail.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Using MEF Exports with Autofac 2</title>
            <link>http://geekswithblogs.net/smitcham/archive/2010/02/12/using-mef-exports-with-autofac-2.aspx</link>
            <description>&lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:d7edc9b8-fd18-40cf-9b53-029a3848b7ed" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;  [Import]
  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; CompositionContainer CompositionContainer { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
  
  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnImportsSatisfied()
  {
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; we replace the imported container with a new one in which we are adding 
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; context specific services.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    CompositionContainer &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; CompositionContainer(CompositionContainer);
      
    var additionalStuff &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; AdditionalStuff();
    var batch &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; CompositionBatch();
    batch.AddExportedValue(additionalStuff);
    
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Items deeper in the context chain are going to import this container&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    batch.AddExportedValue(CompositionContainer);
    
    CompositionContainer.Compose(batch);
  }&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;As a starting point for decoupling this code, I’ve looked into the &lt;a href="http://code.google.com/p/autofac/" target="_blank"&gt;autofac library&lt;/a&gt; which with the version 2 experimental version has some MEF integration support.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://nblumhardt.com/2009/12/lazing-around-with-autofac2/" target="_blank"&gt;example Nicholas Blumhardt uses&lt;/a&gt; the Lazy&amp;lt;T&amp;gt; capabilities of .NET 4, but doesn’t really show the integration with MEF using the Catalog registration services.&lt;/p&gt;

&lt;p&gt;By making some modifications to the code in his example, you can really show how the MEF components can be pulled into the &lt;a href="http://code.google.com/p/autofac/" target="_blank"&gt;autofac&lt;/a&gt; container very easily.&lt;/p&gt;

&lt;p&gt;the first step is to connect the MEF export attributes to the meta data used by the logger imports.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:e6c61278-8155-4c67-80e5-a472e34a9e16" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;interface&lt;/span&gt;&lt;span style="color: #000000;"&gt; ILogAppenderMetadata
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; AppenderName { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
    }

    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class)]
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; LogAppenderAttribute : ExportAttribute, ILogAppenderMetadata
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; LogAppenderAttribute() : &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(ILogAppender))
        {
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; AppenderName { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
    }
&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:518b0d70-62cb-428a-a26c-04f256532dd0" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt; [LogAppender(AppenderName&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;printer&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;)]
 &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; PrinterLogAppender : ILogAppender
  {
  ...
  }
  
  [LogAppender(AppenderName&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;screen&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;)]
  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ScreenLogAppender : ILogAppender
  {
  ...
  }
&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Finally, the Main method is modified to make use of the catalog registration services provided by &lt;a href="http://code.google.com/p/autofac/" target="_blank"&gt;autofac&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;
  &lt;/p&gt;&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:966f1764-f1b8-4a54-93e0-025ed8035ae3" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] args)
  {
    var builder &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ContainerBuilder();
    var catalog &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; TypeCatalog(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt; (PrinterLogAppender), &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt; (ScreenLogAppender));
    builder.RegisterComposablePartCatalog(catalog);
  
    builder.RegisterType&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Program&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;();
    builder.RegisterType&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Log&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;();
  
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; (var container &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; builder.Build())
    {
        container.Resolve&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Program&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;().Run();
    }
  }
&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;


&lt;p&gt;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.&lt;/p&gt; &lt;img src="http://geekswithblogs.net/smitcham/aggbug/137945.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Steven Mitcham</dc:creator>
            <guid>http://geekswithblogs.net/smitcham/archive/2010/02/12/using-mef-exports-with-autofac-2.aspx</guid>
            <pubDate>Fri, 12 Feb 2010 20:33:46 GMT</pubDate>
            <comments>http://geekswithblogs.net/smitcham/archive/2010/02/12/using-mef-exports-with-autofac-2.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/smitcham/comments/commentRss/137945.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/smitcham/services/trackbacks/137945.aspx</trackback:ping>
        </item>
    </channel>
</rss>
