<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Derik Whittaker : MEF</title><link>http://devlicio.us/blogs/derik_whittaker/archive/tags/MEF/default.aspx</link><description>Tags: MEF</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Speaking on MEF at the L’viv .Net Users Group</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2010/06/30/speaking-on-mef-at-the-l-viv-net-users-group.aspx</link><pubDate>Wed, 30 Jun 2010 11:18:40 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:60811</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=60811</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=60811</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2010/06/30/speaking-on-mef-at-the-l-viv-net-users-group.aspx#comments</comments><description>&lt;p&gt;I just confirmed that when I am over in L’viv Ukraine working with our team there (btw, they are a kick @ss team) I will be speaking at the L’viv .Net Users group.&amp;#160; The topic of the night will be &lt;a href="http://code.msdn.microsoft.com/mef"&gt;MEF&lt;/a&gt; (on &lt;a href="http://mef.codeplex.com/"&gt;codeplex&lt;/a&gt;).&amp;#160; &lt;/p&gt;  &lt;p&gt;The Managed Extensibility Framework (MEF) is a new library in .NET that enables greater reuse of applications and components. Using MEF, .NET applications can make the shift from being statically compiled to dynamically composed. If you are building extensible applications, extensible frameworks and application extensions, then MEF is for you. &lt;/p&gt;  &lt;p&gt;If you are in the area and are up for an English based session on MEF please stop by and say hello.&lt;/p&gt;  &lt;p&gt;For more information check out &lt;a href="http://dotnetug-lviv.blogspot.com/"&gt;http://dotnetug-lviv.blogspot.com/&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=60811" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Speaking/default.aspx">Speaking</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/MEF/default.aspx">MEF</category></item><item><title>Quick Lap Around MEF at the Raleigh VS 2010 Road Show</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2010/06/02/quick-lap-around-mef-at-the-raleigh-vs-2010-road-show.aspx</link><pubDate>Thu, 03 Jun 2010 00:02:53 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:59605</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=59605</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=59605</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2010/06/02/quick-lap-around-mef-at-the-raleigh-vs-2010-road-show.aspx#comments</comments><description>&lt;p&gt;Today at the Raleigh VS Southern Road Show which was put on by &lt;a href="http://www.structuretoobig.com/"&gt;Brian Hitney&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/b/glengordon/"&gt;Glenn Gordon&lt;/a&gt; I had a chance to do a 20 minute lightning talk on MEF.&amp;#160; Because I only had 20 minutes, my talk focused on explaining the ‘what and the why’ along with providing 2 (had 3 but only got through 2 of them) straight forward examples on how to use MEF.&lt;/p&gt;  &lt;p&gt;I thought it would be good to attach my slide deck (all 6 slides) along w/ my sample code &lt;a href="http://dimecasts.shared.s3.amazonaws.com/RaleighVS2010_Launch_MEF/LearningMEF_VS2010_LaunchEvent.zip"&gt;here&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Thanks again Brain and Glenn, great show.&lt;/p&gt;  &lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=59605" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Announcement/default.aspx">Announcement</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/MEF/default.aspx">MEF</category></item><item><title>Providing Metadata to your MEF exports</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2010/03/06/providing-metadata-to-you-mef-exports.aspx</link><pubDate>Sun, 07 Mar 2010 01:07:24 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55689</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=55689</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=55689</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2010/03/06/providing-metadata-to-you-mef-exports.aspx#comments</comments><description>&lt;p&gt;Many months ago I created a post on how to get started with &lt;a href="http://devlicio.us/blogs/derik_whittaker/archive/2009/10/27/simple-kick-start-example-using-mef-preview-8.aspx"&gt;MEF&lt;/a&gt;.&amp;#160; Ever since then I have been meaning to get this post (and others) about about how to get up and running quickly with MEF.&lt;/p&gt;  &lt;p&gt;In this post will demonstrate how to provide Metadata (custom values which can help provide context) information to your Exported item.&amp;#160; Why should you care about Metedata?&amp;#160; Below is a great reason from the MEF site on codeplex&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://mef.codeplex.com/wikipage?title=Declaring%20Exports&amp;amp;referringTitle=Exports%20and%20Metadata"&gt;Declaring Exports&lt;/a&gt; explained the basics of parts exporting services and values. In some cases it’s necessary to associate information with exports for a variety of reasons. Commonly it’s used to explain about the capabilities of an specific implementation of a common contract. This is useful to allow imports to either constraint the export that can satisfy it, or to import all available implementations at the time and check their capabilities in runtime before using the export.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Before we get rolling:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;What I am going to show in this post is how to create a custom Export Attribute.&amp;#160; It is possible to expose Meta via the build in ExportAttribute, but the built in mechanism has a few short comings:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Not discoverable &lt;/li&gt;    &lt;li&gt;Not strongly typed &lt;/li&gt;    &lt;li&gt;Compiler cannot validate the data content &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;Lets get rolling:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Pre-Step 1: Taking a look at the Class which we will mark as a Export&lt;/strong&gt;&lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;    public interface IPlugin
    {
        string PluginAction();
    }

    [Export(typeof(IPlugin))]
    public class DefaultPlugin : IPlugin 
    {
        public string PluginAction()
        {
            return &amp;quot;This is the default plugin&amp;quot;;
        }
    }&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Defining the interface which will represent your&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In order to create discoverable Metadata you will first want to create an interface which will represent your metadata.&amp;#160; Below is my interface.&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;    public interface IPluginMetaData
    {
        string Name { get; }
        string Version { get; } 
    }&lt;/pre&gt;

&lt;p&gt;We will later use this interface when we define and use our custom Export Attribute.&amp;#160; The main reason for creating this attribute is now the compiler has a hard wired way to know exactly what type of data is being exposed in your Metadaa&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Defining your custom ExportAttribute Attribute&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that we created our interface to give us strong typing and discoverability we need to create a custom attribute which will allows the MEF engine to know we have Metadata to expose&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class PluginMetadataAttribute : ExportAttribute
    {
        public PluginMetadataAttribute( string name, string version)
            : base(typeof(IPluginMetaData))
        {
            Name = name;
            Version = version;
        }

        public string Name { get; set; }
        public string Version { get; set; }
    }&lt;/pre&gt;

&lt;p&gt;When looking at the code above there are 3 things to pay close attention to&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;You need to make a call into the base constructor of the ExportAttribute and provide it the type of your interface which defines your Metadata &lt;/li&gt;

  &lt;li&gt;You need to mark your attribute with the [MetadataAttribute] (which is part of MEF) &lt;/li&gt;

  &lt;li&gt;You need to mark the usage type of your attribute.&amp;#160; I am not 100% why this is needed (Glenn, you out there with an answer???) &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Providing your Metdata to your Exported Class&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;    [Export(typeof(IPlugin))]
    [PluginMetadata(&amp;quot;Default&amp;quot;, &amp;quot;1.0.0.0&amp;quot;)]
    public class DefaultPlugin : IPlugin 
    {
        public string PluginAction()
        {
            return &amp;quot;This is the default plugin&amp;quot;;
        }
    }&lt;/pre&gt;

&lt;p&gt;The code above is the same as the code we saw in pre-step 1, but this time we have marked the class with our custom Metadata attribute.&amp;#160; We have now officially provided our Metadata to our Export…. But how do we get this information out of MEF?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Setting up your [ImportMany] to use the Metadata&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you are using an ImportMany (this should also work on an Import, but I have never tried) most likely you are pushing your Exports into a IList or IEnumerable.&amp;#160; If this is the case, your changes are pretty minor.&amp;#160; Below is what you need to do in order to have your Metadata loaded.&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;[ImportMany(typeof(IPlugin), AllowRecomposition = true)]
private IList&amp;lt;Lazy&amp;lt;IPlugin, IPluginMetaData&amp;gt;&amp;gt; _loadedIPlugins = new List&amp;lt;Lazy&amp;lt;IPlugin, IPluginMetaData&amp;gt;&amp;gt;();&lt;/pre&gt;

&lt;p&gt;If you have not seen the &lt;a href="http://msdn.microsoft.com/en-us/library/dd642331%28VS.96%29.aspx"&gt;Lazy&lt;/a&gt; keyword, you are not alone.&amp;#160; This is new to .Net 4 and this provides Lazy initialization support to the framework.&amp;#160; (part of the System namespace).&amp;#160; One key thing to understand here though is that the Lazy keyword out the box is only Lazy&amp;lt;T&amp;gt;, but the Lazy we are using is Lazy&amp;lt;T, M&amp;gt;.&amp;#160; This extended version of Lazy lives in the MEF assemblies (System.ComponentModel.Composition) and will need to be referenced to use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Using the Metadata&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once you have the Export loaded into your container (which by the way does not need to change to have this work) you can access your container by selecting the .Metadata property on your instance of the export.&amp;#160; The image below shows it in action.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_0421BA20.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_thumb_5F00_639A7A6D.png" width="180" height="151" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, exposing and using Metadata via MEF is a snap.&amp;#160; &lt;/p&gt;

&lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55689" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Development+Tools/default.aspx">Development Tools</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/MEF/default.aspx">MEF</category></item><item><title>MEF and decrypting LoaderExceptions</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2010/01/31/mef-and-decrypting-loaderexceptions.aspx</link><pubDate>Sun, 31 Jan 2010 14:51:02 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55224</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=55224</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=55224</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2010/01/31/mef-and-decrypting-loaderexceptions.aspx#comments</comments><description>&lt;p&gt;Have you ever received the following exception while using &lt;a href="http://www.codeplex.com/MEF"&gt;MEF&lt;/a&gt;?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;if you have received this error did you scratch your head and wonder ‘what the F does this mean’?&amp;#160; Well the long and short of it is this.&amp;#160; This means that while trying to load an &lt;a href="http://mef.codeplex.com/wikipage?title=Declaring%20Exports&amp;amp;referringTitle=Guide"&gt;Export&lt;/a&gt; there was a dependency which could not be found during reflection.&lt;/p&gt;  &lt;p&gt;The quick way to determine the cause of the error is to do as the image below shows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/MEFException_5F00_54EB0696.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="MEFException" border="0" alt="MEFException" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/MEFException_5F00_thumb_5F00_0B78B1DB.png" width="804" height="104" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;What I would suggest is to wrap your MEF logic inside of a try-catch and explicitly catch &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.reflectiontypeloadexception.aspx"&gt;ReflectionTypeLoadException&lt;/a&gt;.&amp;#160; Inside of your catch add some logic as such (just a PoC, copy-paster beware).&lt;/p&gt;  &lt;pre class="C#" name="code"&gt;catch (ReflectionTypeLoadException tLException)
{
    var loaderMessages = new StringBuilder();
    loaderMessages.AppendLine(&amp;quot;While trying to load composable parts the follwing loader exceptions were found: &amp;quot;);
    foreach (var loaderException in tLException.LoaderExceptions)
    {
        loaderMessages.AppendLine(loaderException.Message);
    }

    // this is one of our custom exception types.
    throw new PluginLoadingException(loaderMessages.ToString(), tLException);
}&lt;/pre&gt;

&lt;p&gt;As you can see when you look at the LoaderExcpetions collections from my image above I had forgotten to reference AutoMapper in my plug-in and all hell broke lose (btw, no idea how this even compiled, but that is a different post).&lt;/p&gt;

&lt;p&gt;Hope this helps.&lt;/p&gt;

&lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55224" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/HowTo/default.aspx">HowTo</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/MEF/default.aspx">MEF</category></item><item><title>Enabling Recomposition in MEF (Preview 8)</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2009/11/16/enabling-recomposition-in-mef-preview-8.aspx</link><pubDate>Mon, 16 Nov 2009 11:05:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:53740</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=53740</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=53740</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2009/11/16/enabling-recomposition-in-mef-preview-8.aspx#comments</comments><description>&lt;p&gt;In my previous post (&lt;a href="http://devlicio.us/blogs/derik_whittaker/archive/2009/10/27/simple-kick-start-example-using-mef-preview-8.aspx"&gt;here&lt;/a&gt;)&amp;nbsp; I showed you how to setup and get running with MEF.&amp;nbsp; However, what I left out from that post is how to setup MEF to allow &amp;lsquo;recomposition&amp;rsquo;, which is the fancy way of saying to allow your application to discover new plugins at run time.&amp;nbsp; Allowing your application to discover new plugins while still running could be a major feature as it could allow you to add/change the behavior without the need to restart.&amp;nbsp; One useful scenario for this could be adding a new rules for a rules engine on the fly.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Goal of this demo?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Show you how you can add in the ability to rediscover exports at runtime with MEF.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;What is needed?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;If you have not already done so head out to &lt;a href="http://mef.codeplex.com/"&gt;http://mef.codeplex.com/&lt;/a&gt; and grab the latest source download.&amp;nbsp; More than likely you will need to download and compile all the source in order to get working binaries (hey, it is a preview after all).&amp;nbsp; Once you have compiled the source you need to grab the output from the ComponentModel project (assembly name is System.ComponentModel.Composition) and include this into your project.&lt;/p&gt;
&lt;p&gt;Also, if you have not taken a look at my previous post (&lt;a href="http://devlicio.us/blogs/derik_whittaker/archive/2009/10/27/simple-kick-start-example-using-mef-preview-8.aspx"&gt;here&lt;/a&gt;) please do so now as I will be building upon that post.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Putting it together?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Configuring your imports to allow recomposition.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;This is one of the great parts of MEF, performing this configuration is CAKE, all you need to do is modify the attribute you have place on your collection as follows&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;[ImportMany(typeof(IRule), AllowRecomposition = true)]
internal IList _rules { get; set; }&lt;/pre&gt;
&lt;p&gt;After you have added the &amp;lsquo;AllowRecomposition&amp;rsquo; attribute you are pretty much done.&amp;nbsp; However, if you would like to be notified (via an event) each time recomposition happens you can do as follows&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;public void Init()
{
    try
    {
        var catalog = new AggregateCatalog();
        var container = new CompositionContainer( catalog );
        var batch = new CompositionBatch();
        batch.AddPart( this );

        catalog.Catalogs.Add( new AssemblyCatalog( Assembly.GetExecutingAssembly() ) );

	// this is the new part
        catalog.Changed += catalog_Changed;

        container.Compose( batch );
    }
    catch ( CompositionException compositionException )
    {
	// testing
        throw;
    }
}

void catalog_Changed( object sender, ComposablePartCatalogChangeEventArgs e )
{
	// do something here
    	var x = &amp;quot;&amp;quot;;
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Wrapping it up&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;As you can see, setting up MEF for recompisition is cake and is really only requires a modification to one line of code.&lt;/p&gt;
&lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=53740" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/.Net/default.aspx">.Net</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/HowTo/default.aspx">HowTo</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/MEF/default.aspx">MEF</category></item><item><title>Simple Kick Start Example using MEF (Preview 8)</title><link>http://devlicio.us/blogs/derik_whittaker/archive/2009/10/27/simple-kick-start-example-using-mef-preview-8.aspx</link><pubDate>Tue, 27 Oct 2009 10:34:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:53159</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/rsscomments.aspx?PostID=53159</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/derik_whittaker/commentapi.aspx?PostID=53159</wfw:comment><comments>http://devlicio.us/blogs/derik_whittaker/archive/2009/10/27/simple-kick-start-example-using-mef-preview-8.aspx#comments</comments><description>&lt;p&gt;If your application needs extension points what do you do? Building a plugin based system is not cutting edge, it is not rocket science.&amp;#160; However, it does take a little effort and can be a bit painful depending on your implementation.&amp;#160; The guys at MS (Glen Block and crew) has been working on this kickin framework for about a year now called the &lt;a href="http://mef.codeplex.com/"&gt;Managed Extensibility Framework&lt;/a&gt; (most commonly known as MEF).&amp;#160; The core goal of MEF is to simplify the creation of extensible applications. MEF offers discovery and composition capabilities that you can leverage to load application extensions.&lt;/p&gt;  &lt;p&gt;There are a metric crap-ton of samples out on the net which show how to get running with MEF, however many of the posts are based off of older previews and most are also incomplete in terms of the code they show you on screen.&amp;#160; What I would like to do is provide a detailed how-to on getting your first (simple) MEF application up and running.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Goal of the demo code?&lt;/b&gt;     &lt;br /&gt;For this demo code we are going to put together a very simple rules plug-in engine.&amp;#160; The goal is to be able to add in a new IRule at any point and have your application pick it up.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;What is needed?      &lt;br /&gt;&lt;/b&gt;If you have not already done so head out to &lt;a title="http://mef.codeplex.com/" href="http://mef.codeplex.com/"&gt;http://mef.codeplex.com/&lt;/a&gt; and grab the latest source download.&amp;#160; More than likely you will need to download and compile all the source in order to get working binaries (hey, it is a preview after all).&amp;#160; Once you have compiled the source you need to grab the output from the ComponentModel project (assembly name is System.ComponentModel.Composition) and include this into your project.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Putting it together?&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;Creating the rule Interface : IRule &lt;/i&gt;    &lt;br /&gt;This is needed because in order to define a plug-in you need to define what that plug-in looks like. &lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;public interface IRule
{
    void DoIt();
    string Name { get; }
    string Version { get; }
    string Description { get; }
}&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;i&gt;Creating a rule instance (or two) 
    &lt;br /&gt;&lt;/i&gt;Now that we have our rule interface we need to create specific instances of the rule and mark them for export.&amp;#160; Marking them for Export simply entails adding a attribute provided by the MEF framework and this attribute allows you to describe your plug-in to the MEF framework so it can pick it up. &lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;[Export( typeof( IRule ) )]
internal class RuleInstance1 : IRule
{
    public void DoIt() {}

    public string Name
    {
        get { return &amp;quot;Rule Instance 1&amp;quot;; }
    }

    public string Version
    {
        get { return &amp;quot;1.0.0.0&amp;quot;; }
    }

    public string Description
    {
        get { return &amp;quot;Some Rule Instance&amp;quot;; }
    }
}

[Export( typeof( IRule ) )]
public class RuleInstance2 : IRule
{
    public void DoIt() {}

    public string Name
    {
        get { return &amp;quot;Rule Instance 3&amp;quot;; }
    }

    public string Version
    {
        get { return &amp;quot;1.1.0.0&amp;quot;; }
    }

    public string Description
    {
        get { return &amp;quot;Some Rule Instance&amp;quot;; }
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;i&gt;Creating the holder for all your plug-ins 
    &lt;br /&gt;&lt;/i&gt;In order to have your application know about the plug-ins that MEF has found you need to define a storage location for them.&amp;#160; We will do this by creating a property of IList&amp;lt;IRule&amp;gt; which will hold each instance.&amp;#160; When we create this storage location we need to tell MEF that we are going to use this as a storage location and to do this you need to mark it with the ImportMany (use this attribute if you want a collection, use Import for only a single instance) attribute.&amp;#160; This is another special attribute provided by the MEF framework. &lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;[ImportMany( typeof( IRule ) )]
internal IList&amp;lt;IRule&amp;gt;: _rules { get; set ;}&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;i&gt;Creating the logic to load the plugin 
    &lt;br /&gt;&lt;/i&gt;Now that we have all the heavy lifting out of the way in terms of defining our Imports and Exports it is time to setup our application to consume the data.&amp;#160; It is here where you tell MEF where to look to find your exports (plug-ins) and what to do with them once you have found them. &lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;public void Init()
{
    var catalog = new AggregateCatalog();
    var container = new CompositionContainer( catalog );
    var batch = new CompositionBatch();
    batch.AddPart( this );
    // because all our types are in the same assembly we simply use the current one.    
    catalog.Catalogs.Add( new AssemblyCatalog( Assembly.GetExecutingAssembly() ) );
    container.Compose( batch );
    foreach ( var rule in _rules )
    {
        Debug.WriteLine( rule.Name );
    }
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Wrapping it up 
    &lt;br /&gt;&lt;/b&gt;As you can see getting a simple example of MEF up and running is a pretty simple task (great job MEF team).&amp;#160; You should be able to get this up and running in about 10 minutes.&amp;#160; You should also have all the code you need in order to get this running.&amp;#160; I hope this helps kick-start someone’s learning and adoption of MEF.&lt;/p&gt;

&lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=53159" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/MEF/default.aspx">MEF</category></item></channel></rss>