<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/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>MEF and more</title><link>http://blogs.msdn.com/hammett/default.aspx</link><description /><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>MEF and ASP.NET MVC sample updated</title><link>http://blogs.msdn.com/hammett/archive/2009/07/15/mef-and-asp-net-mvc-sample-updated.aspx</link><pubDate>Wed, 15 Jul 2009 21:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9834550</guid><dc:creator>hammett</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/hammett/comments/9834550.aspx</comments><wfw:commentRss>http://blogs.msdn.com/hammett/commentrss.aspx?PostID=9834550</wfw:commentRss><description>&lt;p&gt;Sample updated to Preview 6. I've also took the time to simplify the MvcCatalog and to hard set the Creation Policy to Non Shared for all controllers.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;Have fun!&amp;nbsp;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9834550" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/hammett/attachment/9834550.ashx" length="703655" type="application/x-zip-compressed" /></item><item><title>MEF and ASP.NET MVC sample</title><link>http://blogs.msdn.com/hammett/archive/2009/04/23/mef-and-asp-net-mvc-sample.aspx</link><pubDate>Thu, 23 Apr 2009 20:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9565170</guid><dc:creator>hammett</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/hammett/comments/9565170.aspx</comments><wfw:commentRss>http://blogs.msdn.com/hammett/commentrss.aspx?PostID=9565170</wfw:commentRss><description>&lt;H4&gt;Disclaimer&lt;/H4&gt;
&lt;P&gt;First things first, don’t consider this sample an official sample. It is just something I’ve created to illustrate some capabilities of MEF when integrated with ASP.NET MVC in the user-level (as opposed to framework level).&lt;/P&gt;
&lt;P&gt;Also, if you would try to do this integration yourself, you’ll notice at some point that you’ll need to attach metadata to your controllers, so you can grab the right one on the controller factory. In this sample I provide a custom catalog that is aware of controllers, so it adds the metadata itself saving us the burden. Of course, this adds to complexity..&lt;/P&gt;
&lt;P&gt;As MEF targets the extensibility story, this sample is an ASP.NET MVC app that can be “augmented” by new modules. The main app is a shell with almost no functionality. New modules add navigation, controllers, services and consume the services are present on the system.&lt;/P&gt;
&lt;P&gt;The first extension module provide adds Wiki support to the main application. The second, a forum module.&lt;/P&gt;
&lt;P&gt;Bear in mind that everything is fake. I’m showing how to leverage the extensibilities capabilities of MEF, and not how to design a CMS, Forum or Wiki :-)&lt;/P&gt;
&lt;P&gt;In a real world app a similar extensibility mechanism in a web app would also have to deal with database/versioning issues, content resource (additional css, js, images), and so forth.&lt;/P&gt;
&lt;H4&gt;Download&lt;/H4&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/hammett/attachment/9565170.ashx"&gt;MvcWithMEF.zip&lt;/A&gt;&lt;/P&gt;
&lt;H4&gt;Walkthrough&lt;/H4&gt;
&lt;P&gt;You may start by running the app. You should see the following on your browser:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/hammett/WindowsLiveWriter/MEFandASP.NETMVC_89BE/scl1_2.png" mce_href="http://blogs.msdn.com/blogfiles/hammett/WindowsLiveWriter/MEFandASP.NETMVC_89BE/scl1_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=scl1 border=0 alt=scl1 src="http://blogs.msdn.com/blogfiles/hammett/WindowsLiveWriter/MEFandASP.NETMVC_89BE/scl1_thumb_1.png" width=640 height=458 mce_src="http://blogs.msdn.com/blogfiles/hammett/WindowsLiveWriter/MEFandASP.NETMVC_89BE/scl1_thumb_1.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;The links above (forum, wiki) were added dynamically by modules loaded. &lt;/P&gt;
&lt;H4&gt;&lt;/H4&gt;
&lt;H5&gt;Where everything starts&lt;/H5&gt;
&lt;P&gt;The Global.asax.cs holds our bootstrap code:&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Application_Start()&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;{&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;  HostingEnvironment.RegisterVirtualPathProvider(&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; AssemblyResourceVirtualPathProvider());&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;  RegisterRoutes(RouteTable.Routes);&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;  var catalog = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; CatalogBuilder().&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;    ForAssembly(&lt;SPAN class=kwrd&gt;typeof&lt;/SPAN&gt;(IModuleInstaller).Assembly).&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;    ForMvcAssembly(Assembly.GetExecutingAssembly()).&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;    ForMvcAssembliesInDirectory(HttpRuntime.BinDirectory, &lt;SPAN class=str&gt;"*Extension.dll"&lt;/SPAN&gt;). &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;    Build();&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  13:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  14:  &lt;/SPAN&gt;  _container = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; CompositionContainer(catalog);&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  15:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  16:  &lt;/SPAN&gt;  var modules = _container.GetExportedObjects&amp;lt;IModuleInstaller&amp;gt;();&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  17:  &lt;/SPAN&gt;  var navService = _container.GetExportedObject&amp;lt;NavigationService&amp;gt;();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  18:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  19:  &lt;/SPAN&gt;  InitializeModules(modules, navService);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  20:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  21:  &lt;/SPAN&gt;  ControllerBuilder.Current.SetControllerFactory(&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  22:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; MefControllerFactory(_container));&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  23:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre{	font-size: small;	color: black;	font-family: consolas, "Courier New", courier, monospace;	background-color: #ffffff;	/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {	background-color: #f4f4f4;	width: 100%;	margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;The first line sets up a custom VirtualPathProvider that check assembly resources for content. Nothing new. &lt;/P&gt;
&lt;P&gt;Lines 8-12 defines our catalog, which encapsulates the discovery mechanism on MEF. It also provides us opportunities to customize things. In this case, we want to discover things on the Core assembly (line 9), on the executing assembly/web project assembly (line 10), and anything on the web app’s bin folder that ends with Extension.dll (line 11). &lt;/P&gt;
&lt;P&gt;A container is created with a reference to the aggregation of all these catalogs. Right after we retrieve all IModuleInstaller implementations available and start all modules, which is to say we give them a chance to change/add URL routes and add navigation information. &lt;/P&gt;
&lt;P&gt;Finally, we create a custom IControllerFactory instance and set up ASP.NET MVC to use it (line 21).&lt;/P&gt;
&lt;H5&gt;The MEF Controller Factory&lt;/H5&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; MefControllerFactory : IControllerFactory&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;{&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;  &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;const&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; ControllerExportEntryName = &lt;SPAN class=str&gt;"controllerExport"&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;  &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;readonly&lt;/SPAN&gt; CompositionContainer _container;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;  &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; MefControllerFactory(CompositionContainer container)&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;  {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;    _container = container;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;  }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;  &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; IController CreateController(RequestContext requestContext, &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; controllerName)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;  {&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  13:  &lt;/SPAN&gt;    var controllerExport = _container.GetExports&amp;lt;IController&amp;gt;().&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  14:  &lt;/SPAN&gt;      Where(exp =&amp;gt; &lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  15:  &lt;/SPAN&gt;        exp.Metadata.ContainsKey(Constants.ControllerNameMetadataName) &amp;amp;&amp;amp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  16:  &lt;/SPAN&gt;        exp.Metadata[Constants.ControllerNameMetadataName].&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  17:  &lt;/SPAN&gt;          ToString().ToLowerInvariant().&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  18:  &lt;/SPAN&gt;          Equals(controllerName.ToLowerInvariant())).&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  19:  &lt;/SPAN&gt;        FirstOrDefault();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  20:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  21:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (controllerExport == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  22:  &lt;/SPAN&gt;    {&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  23:  &lt;/SPAN&gt;      &lt;SPAN class=kwrd&gt;throw&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; HttpException(404, &lt;SPAN class=str&gt;"Not found"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  24:  &lt;/SPAN&gt;    }&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  25:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  26:  &lt;/SPAN&gt;    requestContext.HttpContext.Items[ControllerExportEntryName] = controllerExport;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  27:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  28:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; controllerExport.GetExportedObject();&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  29:  &lt;/SPAN&gt;  }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  30:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  31:  &lt;/SPAN&gt;  &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; ReleaseController(IController controller)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  32:  &lt;/SPAN&gt;  {&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  33:  &lt;/SPAN&gt;    var export = HttpContext.Current.Items[ControllerExportEntryName] &lt;SPAN class=kwrd&gt;as&lt;/SPAN&gt; Export&amp;lt;IController&amp;gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  34:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  35:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (export != &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  36:  &lt;/SPAN&gt;    {&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  37:  &lt;/SPAN&gt;      _container.ReleaseExport(export);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  38:  &lt;/SPAN&gt;    }&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  39:  &lt;/SPAN&gt;  }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  40:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre{	font-size: small;	color: black;	font-family: consolas, "Courier New", courier, monospace;	background-color: #ffffff;	/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {	background-color: #f4f4f4;	width: 100%;	margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;This implementation, albeit short, shows interests aspects. First, on the CreateController, we get all exports of IController – which is different from getting all _instances_ of IController. Then, we use the metadata associated with those Exports to find the controller we need to get an instance. &lt;/P&gt;
&lt;P&gt;We hold this export instance for the duration of this request (HttpContext.Items), so we can use it on ReleaseController. This relies on the assumption that in a request only one controller is instantiated. &lt;/P&gt;
&lt;P&gt;The ReleaseController get back that export instance and calls Container.ReleaseExport, which will go over all the object graph, and properly release and dispose NonShared / Disposable instances. If you miss this step you will be in a route to a memory bloat as every controller is non shared and disposable. &lt;/P&gt;
&lt;H5&gt;The MVC Catalog&lt;/H5&gt;
&lt;P&gt;This one is a bit more complex, but remember, it is an optional step. I just added it because I’m lazy and didn’t want to add metadata to every controller (it would be a violation of DRY too.) &lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; MvcCatalog : ComposablePartCatalog, ICompositionElement&lt;/PRE&gt;&lt;PRE&gt;{&lt;/PRE&gt;&lt;PRE class=alt&gt;  &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;readonly&lt;/SPAN&gt; Type[] _types;&lt;/PRE&gt;&lt;PRE&gt;  &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;readonly&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; _locker = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt;();&lt;/PRE&gt;&lt;PRE class=alt&gt;  &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; IQueryable&amp;lt;ComposablePartDefinition&amp;gt; _parts;&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;  &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; MvcCatalog(&lt;SPAN class=kwrd&gt;params&lt;/SPAN&gt; Type[] types)&lt;/PRE&gt;&lt;PRE&gt;  {&lt;/PRE&gt;&lt;PRE class=alt&gt;    _types = types;&lt;/PRE&gt;&lt;PRE&gt;  }&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;  &lt;SPAN class=rem&gt;// More constructors //&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;  &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;override&lt;/SPAN&gt; IQueryable&amp;lt;ComposablePartDefinition&amp;gt; Parts&lt;/PRE&gt;&lt;PRE class=alt&gt;  {&lt;/PRE&gt;&lt;PRE&gt;    get { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; InternalParts; }&lt;/PRE&gt;&lt;PRE class=alt&gt;  }&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;  &lt;SPAN class=kwrd&gt;internal&lt;/SPAN&gt; IQueryable&amp;lt;ComposablePartDefinition&amp;gt; InternalParts&lt;/PRE&gt;&lt;PRE&gt;  {&lt;/PRE&gt;&lt;PRE class=alt&gt;    get&lt;/PRE&gt;&lt;PRE&gt;    {&lt;/PRE&gt;&lt;PRE class=alt&gt;      &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (_parts == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;      {&lt;/PRE&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=kwrd&gt;lock&lt;/SPAN&gt;(_locker)&lt;/PRE&gt;&lt;PRE&gt;        {&lt;/PRE&gt;&lt;PRE class=alt&gt;          &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (_parts == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;          {&lt;/PRE&gt;&lt;PRE class=alt&gt;            var partsCollection = &lt;/PRE&gt;&lt;PRE&gt;              &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; List&amp;lt;ComposablePartDefinition&amp;gt;();&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=kwrd&gt;foreach&lt;/SPAN&gt;(var type &lt;SPAN class=kwrd&gt;in&lt;/SPAN&gt; _types)&lt;/PRE&gt;&lt;PRE class=alt&gt;            {&lt;/PRE&gt;&lt;PRE&gt;              var typeCatalog = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; TypeCatalog(type);&lt;/PRE&gt;&lt;PRE class=alt&gt;              var part = typeCatalog.Parts.FirstOrDefault();&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;              &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (part == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;) &lt;SPAN class=kwrd&gt;continue&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;              &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;typeof&lt;/SPAN&gt;(IController).IsAssignableFrom(type))&lt;/PRE&gt;&lt;PRE&gt;              {&lt;/PRE&gt;&lt;PRE class=alt&gt;                part = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;/PRE&gt;&lt;PRE&gt;                  ControllerPartDefinitionDecorator(&lt;/PRE&gt;&lt;PRE class=alt&gt;                    part, &lt;/PRE&gt;&lt;PRE&gt;                    type, &lt;/PRE&gt;&lt;PRE class=alt&gt;                    type.Name, &lt;/PRE&gt;&lt;PRE&gt;                    type.Namespace);&lt;/PRE&gt;&lt;PRE class=alt&gt;              }&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;              partsCollection.Add(part);&lt;/PRE&gt;&lt;PRE&gt;            }&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;            Thread.MemoryBarrier();&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;            _parts = partsCollection.AsQueryable();&lt;/PRE&gt;&lt;PRE class=alt&gt;          }&lt;/PRE&gt;&lt;PRE&gt;        }&lt;/PRE&gt;&lt;PRE class=alt&gt;      }&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;      &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _parts;&lt;/PRE&gt;&lt;PRE&gt;    }&lt;/PRE&gt;&lt;PRE class=alt&gt;  }&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre{	font-size: small;	color: black;	font-family: consolas, "Courier New", courier, monospace;	background-color: #ffffff;	/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {	background-color: #f4f4f4;	width: 100%;	margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;What we’re doing here is: for each type discovered – is a MEF part – we also check if it happens to be a controller. If so, we decorate that part to add an additional export. This export has all the extra metadata that we need to query for that controller later on. &lt;/P&gt;
&lt;H5&gt;&lt;/H5&gt;
&lt;H5&gt;Wiring&lt;/H5&gt;
&lt;P&gt;As we’re using MEF for extensibility we might just as well use it for typical composition – as long as our requirements are low compared to the use of a full fledge IoC Container. &lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;[Export, PartCreationPolicy(CreationPolicy.NonShared)]&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; ForumController : BasePublicController&lt;/PRE&gt;&lt;PRE class=alt&gt;{&lt;/PRE&gt;&lt;PRE&gt;  &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;readonly&lt;/SPAN&gt; ForumService _forumService;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;  [ImportingConstructor]&lt;/PRE&gt;&lt;PRE class=alt&gt;  &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; ForumController(ForumService forumService)&lt;/PRE&gt;&lt;PRE&gt;  {&lt;/PRE&gt;&lt;PRE class=alt&gt;    _forumService = forumService;&lt;/PRE&gt;&lt;PRE&gt;  }&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;  &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; ActionResult Index()&lt;/PRE&gt;&lt;PRE class=alt&gt;  {&lt;/PRE&gt;&lt;PRE&gt;    ViewData[&lt;SPAN class=str&gt;"forums"&lt;/SPAN&gt;] = _forumService.GetEnabledForumsRecentActivity();&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;    &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; View(ViewRoot + &lt;SPAN class=str&gt;"Index.aspx"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE class=alt&gt;  }&lt;/PRE&gt;&lt;PRE&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;In this controller we import (depend) ForumService, which itself depends on IForumRepository. If you don’t mind the extra noise of attributes, MEF can also cover this aspect of your app – but remember, it wasn’t built to be an IoC Container as the ones out there – more on that in another day. &lt;/P&gt;
&lt;H4&gt;Conclusion&lt;/H4&gt;
&lt;P&gt;In the user-level integration MEF plays very well with ASP.NET MVC to enable extensibility on web apps. Of course, this is not the whole story. Like I mentioned, database schema updates/version, making additional content available (js, css, images) and UI Composition are challenging things themselves, but solvable – been there, done that. &lt;/P&gt;
&lt;P&gt;With MEF you have one less thing to worry about in this challenging problem space. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Update:&lt;/STRONG&gt; Kamil spot the fact that my decorator is leaving out one member, and that essentially makes it ignore the creation policy (which is attached to the part definition, not exports). Sample updated.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9565170" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/hammett/attachment/9565170.ashx" length="685522" type="application/x-zip-compressed" /></item><item><title>Dependencies, ownership and lifetime</title><link>http://blogs.msdn.com/hammett/archive/2008/10/16/dependencies-ownership-and-lifetime.aspx</link><pubDate>Fri, 17 Oct 2008 01:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9002444</guid><dc:creator>hammett</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/hammett/comments/9002444.aspx</comments><wfw:commentRss>http://blogs.msdn.com/hammett/commentrss.aspx?PostID=9002444</wfw:commentRss><description>&lt;P&gt;First of all, this blog post contains my own views and does not necessarily reflect the view of employer.&lt;/P&gt;
&lt;P&gt;MEF is a complex small project, dealing with a big and complex problem. In our team a feature crew - a PM, dev and tester - owns a feature. We research, brainstorm, prototype to exhaustion, come up with real world scenarios, brainstorm some more and then finally a spec is produced (or finalized). I'm on the lifetime feature crew. Our goal is to decide and propose a solution on how MEF should deal with lifetime. &lt;/P&gt;
&lt;P&gt;There is a broad range of possible solutions, from not supporting anything at all (which is a valid option) to support a full extensible (and possibly complex) lifetime story. Things to consider are:&lt;/P&gt;
&lt;P&gt;- Being part of the core framework comes with responsabilities. All dogmas should be left on the door, and a solution should be compatible with how the rest of the framework (and its guidelines)&lt;BR&gt;- MEF is not an full fledge IoC, and as such it shouldn't need to behave as one&lt;BR&gt;- The final solution should translate into a predictable behavior for users (more on that below)&lt;/P&gt;
&lt;P&gt;The rest of the post is me sharing (with authorization) some of our findings, some of tough calls to make, and kindly asking for feedback :-)&lt;/P&gt;
&lt;P&gt;In case you're not familiar, lifetime is a concept widely used on component frameworks, especially IoC containers. However it's not 100% adopted, and it might use different names. It defines the scope of accessibility and how (or better, if) an instance can be shared. Singleton is a common lifetime. So is Transient. &lt;/P&gt;
&lt;P&gt;Windsor (and back to Apache Avalon/Excalibur) refers to them as lifestyle instead, and supports Singleton, Transient, Pooled, PerThread and PerWebRequest out of box. It's relatively easy to add a new one. Spring supports Singleton and Transient (which it calls Prototype). The Java version of spring brings extensibility points so you can add new ones. PicoContainer supports only Singletons - new lifetimes can be supported using child container (and carefully registering the components on correctly in the container hierarchy). Autofac supports both singleton and transient, and also relies on container hierarchies to support others.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Outside of the realm of IoC container you can still see similar concepts on OSGi, EJB, COM+ and .Net Remoting. Take the last as a more reachable example, the WellKnownObjectMode enum reads Singleton, SingleCall, which is essentially the same Singleton/Transient pair supported by some IoC containers. &lt;/P&gt;
&lt;P&gt;All is good, but then you face the challenges that this simple concept brings with it.&lt;/P&gt;
&lt;H2&gt;Incompatible Lifetimes &lt;/H2&gt;
&lt;P&gt;Not all lifetimes are compatible with each other. You won't have problems as long as it goes bottom up, from most restricted lifetimes depending on things served but more broad lifetimes. For instance, it's OK to have a per-web-request component that has a dependency on a per-session lifetime, which itself has dependencies on singletons. The opposite is not true, though. &lt;/P&gt;
&lt;H2&gt;Lifetimes that maps to non-boundaries context &lt;/H2&gt;
&lt;P&gt;Singletons can be mapped to the life of the container. You shutdown the container and all singletons are shutdown too. Per-session has a clearly boundary (session starts/ends) and so does per-web-request. &lt;/P&gt;
&lt;P&gt;What about Transients? They can be map to the container lifetime too, but would that mean that we only shutdown them when the container is disposed? That would lead to growing memory consuption in some apps scenarios. What about per-thread? Do we get a notification we a thread is about to start and when it's about to die? &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;Ownership &lt;/H2&gt;
&lt;P&gt;This is not entirely related to lifetime, rather a common OOP problem. Usually you're forced to read the documentation to find out how you're suppose to deal with an object under a particular situation, as the API usually wont be able to tell you. Consider the following:&lt;/P&gt;&lt;PRE&gt;FileStream fs = ...

var processor = new FileProcessor(fs);
processor.Process();&lt;/PRE&gt;
&lt;P&gt;FileStream clearly needs to be disposed. By externally creating it and passing to some other object, do you implicitly transfer the ownership? Some will say yes, some will say no. Others will go with "depends". &lt;/P&gt;
&lt;P&gt;IMHO, for the sample above you do not transfer ownership, so the creator (you) have to dispose it. However if the FileProcessor itself created the FileStream, than it would have the ownership and the obligation to dispose it. Yes, I know, we have finalizers, but the way I see they are safeguards more than anything else. I'll come back to this.&lt;/P&gt;
&lt;P&gt;Fixing our code:&lt;/P&gt;&lt;PRE&gt;using(FileStream fs = ...)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; var processor = new FileProcessor(fs);
&amp;nbsp;&amp;nbsp;&amp;nbsp; processor.Process();
}
&lt;/PRE&gt;
&lt;P&gt;The devil is in the details, though. What if FileProcessor is a long lived instance, that process the file in response to some external stimulus? In that case, the code above will early dipose a stream that the processor will need later.&amp;nbsp; &lt;BR&gt;&amp;nbsp;&lt;BR&gt;Yeah, things are not as easy as they seem. You can come up with something that defines clear contracts, though:&lt;/P&gt;&lt;PRE&gt; 
var processor = new FileProcessor(new FileAccessor(new DirectoryInfo("./files")));
&lt;/PRE&gt;&lt;BR&gt;&amp;nbsp;&lt;BR&gt;Depending on the FileAccessor API it would be more or less clear whose the ownership of file. 
&lt;P&gt;A stream is a relatively straingforward example as it's something that is clearly unshareable. Now consider an even worse situation:&lt;/P&gt;&lt;PRE&gt;var sender = new FtpSender();

var backupSvc = new BackupService(sender);
var docBrw = new DocumentUploaderService(sender);
&lt;/PRE&gt;
&lt;P&gt;FtpSender implements IDisposable, which closes the outgoing transfers and the main connection. Should the dependant services ever dispose them? Clearly no, as it's being shared. But how will the BackupService ever know it's shared? Same thing applies for DocumentUploaderService.&lt;/P&gt;
&lt;P&gt;As someone who things conventions (and by consequence guidelines) tend to result in good things, I'd say that it would be safer to rely on a simple convetion: whoever created something has the obligation of destroying it. Obviously that will only apply to instances that have some sort of shutdown semantics like Stop, Close or Dispose. &lt;/P&gt;
&lt;P&gt;Bringing all that to IoC containers. Windsor has always encouraged that. You don't care how things ended up on your constructor or properties, and you shouldn't care. In order words: &amp;lt;b&amp;gt;Thou shall shutdown them explicitly&amp;lt;/b&amp;gt;.&lt;/P&gt;
&lt;P&gt;Spring, however, deals with shutdown semantics for singleton, but leaves it up to you in the case of transients. I disagree with this as I find troublesome to have to know the lifetime of my dependencies and act accordingly - IMHO I shouldn't have to care - but I deeply understand their reasons. Here's why:&lt;/P&gt;
&lt;P&gt;First, in order to shutdown short lived instances, you need to expose an operation to do that. Windsor and Ninject expose a Release method on the container interface. &amp;lt;i&amp;gt;What happens if the user doesn't call it? &amp;lt;/i&amp;gt;&lt;/P&gt;
&lt;P&gt;Secondly, imagine that you have instances that don't care for shutdown, but later on on the dependency chain there's a instance who cares. Guess what. You'll need to keep a chain of references in order to dispose that last one - what I like to call component burden (there is room for optimizations on the implementation algorithm, though). Why you need the chain? Because Release will be called on the first (root) instance. &lt;/P&gt;
&lt;P&gt;So all in all, while it's easy to put an statement defining how ownership should be handled it does make things _way_ complex. There's a balance however, on what is the right behavior we should strive for, and what's a problem without a good solution that we shouldn't spend energy trying to fix as there is no fix good enough anyway. &lt;/P&gt;
&lt;P&gt;What about the finalizer? Like I said, it's a good safe guard, but I rarely use it. You should be aware that instantiating an object that uses finalizer is more expensive. Also, in the call to finalizer I'm not supposed to reference other instances (ie dispose things other than wild unmanaged resource) as there is not invocation ordering guaranted. Maybe I'm spoilled by the fact that I've always relied on IoC container to do the proper shutdown for me. Implementing IStartable and IDisposable always meant that Windsor will call them, in the right time. Not having to rely on "what if" situations made my code simpler and allowed me to focus on other things. Boilerplate is for frameworks, my code should be about domain. &lt;/P&gt;
&lt;P&gt;Now, I'm interested in hear from you basically two things:&lt;/P&gt;
&lt;P&gt;- Do you often rely on shutdown semantics on your components?&lt;BR&gt;- What do you fell MEF should support?&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9002444" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/hammett/archive/tags/MEF/default.aspx">MEF</category></item><item><title>Introductions</title><link>http://blogs.msdn.com/hammett/archive/2008/08/13/introductions.aspx</link><pubDate>Thu, 14 Aug 2008 09:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8864889</guid><dc:creator>hammett</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/hammett/comments/8864889.aspx</comments><wfw:commentRss>http://blogs.msdn.com/hammett/commentrss.aspx?PostID=8864889</wfw:commentRss><description>&lt;p&gt;If you don't know me my name is Hamilton Verissimo, and I recently joined the MEF team at MS (DevDiv). I'll use this blog to talk about MEF and - give me some time to settle in - other things I plan to be involved with.&amp;nbsp; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;My &lt;a href="http://hammett.castleproject.org/" mce_href="http://hammett.castleproject.org/"&gt;other blog&lt;/a&gt; will be kept but exclusively for Castle related stuff. &lt;br&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8864889" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/hammett/archive/tags/General/default.aspx">General</category></item></channel></rss>