<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://shazwazza.com/rss/xslt"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title>Shazwazza</title>
    <link>https://shazwazza.com/</link>
    <description>My blog which is pretty much just all about coding</description>
    <generator>Articulate, blogging built on Umbraco</generator>
    <image>
      <url>/media/0libq25y/frog.png?rmode=max&amp;v=1da0e911f4e6890</url>
      <title>Shazwazza</title>
      <link>https://shazwazza.com/</link>
    </image>
    <item>
      <guid isPermaLink="false">1221</guid>
      <link>https://shazwazza.com/post/developing-a-plugin-framework-in-aspnet-mvc-with-medium-trust/</link>
      <category>ASP.Net</category>
      <category>Umbraco</category>
      <title>Developing a plugin framework in ASP.NET MVC with medium trust</title>
      <description>&lt;p&gt;I’ve recently spent quite a lot of time researching and prototyping different ways to create a plugin engine in ASP.NET MVC3 and primarily finding a nice way to load plugins (DLLs) in from outside of the ‘bin’ folder. Although this post focuses on MVC3, I am sure that the same principles will apply for other MVC versions. &lt;/p&gt; &lt;h1&gt;The Issues&lt;/h1&gt; &lt;p&gt;Loading DLLs from outside of the ‘bin’ folder isn’t really anything new or cutting edge, however when working with MVC this becomes more difficult. This is primarily due to how MVC loads/finds types that it needs to process including controllers, view models (more precisely the generic argument passed to a &lt;a href="http://www.google.com.au/url?sa=t&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CBkQFjAA&amp;amp;url=http%3A%2F%2Fmsdn.microsoft.com%2Fes-es%2Flibrary%2Fdd470798.aspx&amp;amp;rct=j&amp;amp;q=ViewPage%20msdn&amp;amp;ei=BLAmTd_lPIeycfL36ZgB&amp;amp;usg=AFQjCNFTkQSor1HJFAMkHw0h3BUiiIuEzg&amp;amp;cad=rja" target="_blank"&gt;ViewPage&lt;/a&gt; or used with the @model declaration in Razor), model binders, etc… MVC is very tied to the &lt;a href="http://www.google.com.au/url?sa=t&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CBUQFjAA&amp;amp;url=http%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fsystem.web.compilation.buildmanager.aspx&amp;amp;rct=j&amp;amp;q=BuildManager%20msdn%20asp.net&amp;amp;ei=5LAmTa6nFsn4cbKezYEB&amp;amp;usg=AFQjCNH96gOQZt36Kjh-lIs5CKmWEtPjCA&amp;amp;cad=rja" target="_blank"&gt;BuildManager&lt;/a&gt; which is the mechanism for compiling views, and locating other services such as controllers. By default the BuildManager is only familiar with assembies in the ‘bin’ folder and in the GAC, so if you start putting DLLs in folders outside of the ‘bin’ then it won’t be able to locate the MVC services and objects that you might want it to be referencing.&lt;/p&gt; &lt;p&gt;Another issue that needs to be dealt with is DLL file locking. When a plugin DLL is loaded and is in use the CLR will lock the file. This becomes an an issue if developers want to update the plugin DLL while the website is running since they won’t be able to unless they bump the web.config or take the site down. This holds true for &lt;a href="http://msdn.microsoft.com/en-us/library/dd460648.aspx" target="_blank"&gt;MEF&lt;/a&gt; and how it loads DLLs as well.&lt;/p&gt; &lt;h1&gt;.Net 4 to the rescue… almost&lt;/h1&gt; &lt;p&gt;One of the new features in .Net 4 is the ability to execute code before the app initializes which compliments another new feature of the BuildManager that lets you add assembly references to it at runtime (which must be done on application pre-init). Here’s a nice little reference to these new features from Phil Haack: &lt;a title="http://haacked.com/archive/2010/05/16/three-hidden-extensibility-gems-in-asp-net-4.aspx" href="http://haacked.com/archive/2010/05/16/three-hidden-extensibility-gems-in-asp-net-4.aspx"&gt;http://haacked.com/archive/2010/05/16/three-hidden-extensibility-gems-in-asp-net-4.aspx&lt;/a&gt;.&amp;nbsp; This is essential to making a plugin framework work with MVC so that the BuildManager knows where to reference your plugin DLLs outside of the ‘bin’. However, this isn’t the end of the story. &lt;/p&gt; &lt;h2&gt;Strongly typed Views with model Types located in plugin DLLs&lt;/h2&gt; &lt;p&gt;Unfortunately if you have a view that is strongly typed to a model that exists outside of the ‘bin’, then you’ll find out very quickly that it doesn’t work and it won’t actually tell you why. This is because the &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx" target="_blank"&gt;RazorViewEngine&lt;/a&gt;&amp;nbsp; uses the BuildManager to compile the view into a dynamic assembly but then uses &lt;em&gt;Activator.CreateInstance&lt;/em&gt; to instantiate the newly compiled object. This is where the problem lies, the current AppDomain doesn’t know how to resolve the model Type for the strongly typed view since it doesn’t exist in the ‘bin’ or GAC.&amp;nbsp; An even worse part about this scenario is that you don’t get any error message telling you why this isn’t working, or where the problem is. Instead you get the nice MVC view not found error: “…&lt;i&gt;or its master was not found or no view engine supports the searched locations. The following locations were searched: ….”&lt;/i&gt; telling you that it has searched for views in all of the ViewEngine locations and couldn’t find it… which is actually not the error at all.&amp;nbsp; Deep in the MVC3 source, it tries to instantiate the view object from the dynamic assembly and it fails so it just keeps looking for that view in the rest of the ViewEngine paths.&lt;/p&gt; &lt;p&gt;&lt;em&gt;NOTE: Even though in MVC3 there’s a new &lt;a href="http://bradwilson.typepad.com/blog/2010/10/service-location-pt11-view-page-activator.html" target="_blank"&gt;IViewPageActivator&lt;/a&gt; which should be responsible for instantiating the views that have been compiled with the BuildManager, implementing a custom IViewPageActivator to handle this still does not work because somewhere in the MVC3 codebase fails before the call to the IViewPageActivator which has to do with resolving an Assembly that is not in the ‘bin’. &lt;/em&gt;&lt;/p&gt; &lt;h1&gt;Full trust&lt;/h1&gt; &lt;p&gt;When working in &lt;a href="http://msdn.microsoft.com/en-us/library/wyts434y.aspx" target="_blank"&gt;Full Trust&lt;/a&gt; we have a few options for dealing with the above scenario:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Use the AppDomain’s &lt;a href="http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve.aspx" target="_blank"&gt;ResolveAssembly&lt;/a&gt; event  &lt;ul&gt; &lt;li&gt;By subscribing to this event, you are able to instruct the AppDomain where to look when it can’t find a reference to a Type.  &lt;li&gt;This is easily done by checking if your plugin assemblies match the assembly being searched for, and then returning the Assembly object if found: &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt; &lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:1991111b-18f6-447d-b453-b6a3a4f22a0b" class="wlWriterSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style="overflow: auto; height: 152px; width: 680px; background-color: white"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt;&lt;span style="color: #000000"&gt; Assembly CurrentDomain_AssemblyResolve(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&lt;span style="color: #000000"&gt; sender, ResolveEventArgs args)
{
    var pluginsFolder &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; DirectoryInfo(HostingEnvironment.MapPath(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;~/Plugins&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;return&lt;/span&gt;&lt;span style="color: #000000"&gt; (from f &lt;/span&gt;&lt;span style="color: #0000ff"&gt;in&lt;/span&gt;&lt;span style="color: #000000"&gt; pluginsFolder.GetFiles(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;*.dll&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;, SearchOption.AllDirectories)
            let assemblyName &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; AssemblyName.GetAssemblyName(f.FullName)
            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;where&lt;/span&gt;&lt;span style="color: #000000"&gt; assemblyName.FullName &lt;/span&gt;&lt;span style="color: #000000"&gt;==&lt;/span&gt;&lt;span style="color: #000000"&gt; args.Name &lt;/span&gt;&lt;span style="color: #000000"&gt;||&lt;/span&gt;&lt;span style="color: #000000"&gt; assemblyName.FullName.Split(&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;,&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: #800080"&gt;0&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: #000000"&gt; args.Name
            select Assembly.LoadFile(f.FullName)).FirstOrDefault();
}&lt;/span&gt;&lt;/div&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;ul&gt;
&lt;li&gt;Shadow copy your plugin DLLs into the AppDomain’s &lt;a href="http://msdn.microsoft.com/en-us/library/system.appdomain.dynamicdirectory.aspx" target="_blank"&gt;DynamicDirectory&lt;/a&gt;. 
&lt;ul&gt;
&lt;li&gt;This is the directory that the BuildManager compiles it’s dynamic assemblies into and is also a directory that the AppDomain looks to when resolving Type’s from Assemblies. 
&lt;li&gt;You can shadow copy your plugin DLLs to this folder on app pre-init and everything ‘should just work’ &lt;/li&gt;&lt;/ul&gt;
&lt;li&gt;Replace the RazorViewEngine with a custom razor view engine that compiles views manually but makes references to the appropriate plugin DLLs 
&lt;ul&gt;
&lt;li&gt;I actually had this working in an &lt;a href="http://umbraco.org" target="_blank"&gt;Umbraco&lt;/a&gt; v5 prototype but it is hugely overkill and unnecessary plus you actually would have to replace the RazorViewEngine which is pretty absurd. &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;h1&gt;The burden of Medium Trust&lt;/h1&gt;
&lt;p&gt;In the MVC world there’s only a couple hurdles to jump when loading in plugins from outside of the ‘bin’ folder in Full Trust. In Medium Trust however, things get interesting. Unfortunately in Medium Trust it is not possible to handle the AssemblyResolve event and it’s also not possible to access the DynamicDirectory of the AppDomain so the above two solutions get thrown out the window. Further to this it seems as though you can’t use CodeDom in Medium Trust to custom compile views.&lt;/p&gt;
&lt;h2&gt;Previous attempts&lt;/h2&gt;
&lt;p&gt;For a while I began to think that this wasn’t possible and I thought I tried everything:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shadow copying DLLs from the plugins folder into the ‘bin’ folder on application pre-init 
&lt;ul&gt;
&lt;li&gt;This fails because even during app pre-init, the application pool will still recycle. Well, it doesn’t actually ‘fail’ unless you keep re-copying the DLL into the bin. If you check if it already exists and don’t copy into the bin than this solution will work for you but it’s hardly a ‘solution’ since you might as well just put all your DLLs into the ‘bin’ in the first place. &lt;/li&gt;&lt;/ul&gt;
&lt;li&gt;Trying to use sub folders of the ‘bin’ folder to load plugins. 
&lt;ul&gt;
&lt;li&gt;Turns out that ASP.Net doesn’t by default load in DLLs that exist in sub folders of the bin, though from research it looks like standard .Net apps actually do. 
&lt;li&gt;Another interesting point was that if you try to copy a DLL into a sub folder of the bin during application pre-init you get a funky error:&amp;nbsp; “Storage scopes cannot be created when _AppStart is executing”. It seems that ASP.Net is monitoring all changes in the bin folder regardless of whether or not they are in sub folders but still doesn’t load or reference those assemblies. &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;h2&gt;An easy solution&lt;/h2&gt;
&lt;p&gt;So, the easy solution is to just set a &lt;a href="http://msdn.microsoft.com/en-us/library/823z9h8w%28vs.71%29.aspx" target="_blank"&gt;‘privatePath’ on the ‘probing’ element&lt;/a&gt; in your web.config to tell the AppDomain to also look for Assemblies/Types in the specified folders. I did try this before when trying to load plugins from sub folders in the bin and couldn’t get it to work. I’m not sure if I was ‘doing it wrong’ but it definitely wasn’t working then, either that or attempting to set this in sub folders of the bin just doesn’t work.&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:f5d93897-6e1d-4814-bf75-c9e4c57ad588" class="wlWriterSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style="overflow: auto; height: 68px; width: 680px; background-color: white"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;runtime&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: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;assemblyBinding xmlns&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;urn:schemas-microsoft-com:asm.v1&lt;/span&gt;&lt;span style="color: #800000"&gt;"&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: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;probing privatePath&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;Plugins/temp&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: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/div&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;h1&gt;DLL file locking&lt;/h1&gt;
&lt;p&gt;Since plugin DLLs get locked by the CLR when they are loaded, we need to work around this. The solution is to shadow copy the DLLs to another folder on application pre-init. As mentioned previously, this is one of the ways to get plugins loaded in Full Trust and in my opinion is the nicest way to do it since it kills 2 birds with one stone. In Medium Trust however, we’ll have to jump through some hoops and shadow copy the DLLs to a temp folder that exists within the web application. IMPORTANT: When you’re copying DLLs you might be tempted to modify the name of the DLL by adding a version number or similar, but this will NOT work and you’ll get a &lt;em&gt;“The located assembly's manifest definition … does not match the assembly reference.” &lt;/em&gt;exception.&lt;/p&gt;
&lt;h1&gt;Solution&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;&lt;font size="2"&gt;UPDATE: The latest version of this code can be found in the Umbraco v5 source code. The following code does work but there’s been a lot of enhancements to it in the Umbraco core. Here’s the latest changeset as of 16/16/2012 &lt;a href="https://bitbucket.org/Shandem/umbracov5/src/bc972b4dd5f8/Source/Libraries/Umbraco.Cms.Web/System/PluginManager.cs" target="_blank"&gt;Umbraco v5 PluginManager.cs&lt;/a&gt;&lt;/font&gt;&lt;/em&gt;&lt;em&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Working in Full Trust, the simplest solution is to shadow copy your plugin DLLs into your AppDomain DynamicDirectory. Working in Medium Trust you’ll need to do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On application pre-init: 
&lt;ul&gt;
&lt;li&gt;Shadow copy all of your plugin DLLs to a temporary folder in your web application (not in the ‘bin’) 
&lt;li&gt;Add all of the copied DLLs to be referenced by the BuildManager &lt;/li&gt;&lt;/ul&gt;
&lt;li&gt;Add all folder paths to the &lt;em&gt;privatePath&lt;/em&gt; attribute of the &lt;em&gt;probing&lt;/em&gt; element in your web.config to point to where you will be copying your DLLs 
&lt;ul&gt;
&lt;li&gt;If you have more than one, you need to semi-colon separate them &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Thanks to &lt;a href="http://twitter.com/gblock" target="_blank"&gt;Glenn Block&lt;/a&gt; @ Microsoft who gave me a few suggestions regarding DLL file locking with MEF, Assembly load contexts and probing paths! You put me back on track after I had pretty much given up.&lt;/p&gt;
&lt;p&gt;Here’s the code to do the shadow copying and providing the Assemblies to the BuildManager on application pre-init (&lt;em&gt;make sure you set the privatePath on the probing element in your web.config first!!&lt;/em&gt;)&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:6bc6b791-155d-43bb-a79a-06f5660a311f" class="wlWriterSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style="overflow: auto; height: 708px; width: 680px; background-color: white"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt; System.Linq;
&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt; System.Web;
&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt; System.IO;
&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt; System.Web.Hosting;
&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt; System.Web.Compilation;
&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt; System.Reflection;

[assembly: PreApplicationStartMethod(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000"&gt;(PluginFramework.Plugins.PreApplicationInit), &lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;Initialize&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;namespace&lt;/span&gt;&lt;span style="color: #000000"&gt; PluginFramework.Plugins
{
    &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; PreApplicationInit
    {

        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt;&lt;span style="color: #000000"&gt; PreApplicationInit()
        {
            PluginFolder &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; DirectoryInfo(HostingEnvironment.MapPath(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;~/plugins&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;));
            ShadowCopyFolder &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; DirectoryInfo(HostingEnvironment.MapPath(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;~/plugins/temp&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: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;
        &lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt; The source plugin folder from which to shadow copy from
        &lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;
        &lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;
        &lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt; This folder can contain sub folderst to organize plugin types
        &lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;
&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;static&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000"&gt; DirectoryInfo PluginFolder;

        &lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;
        &lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt; The folder to shadow copy the plugin DLLs to use for running the app
        &lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;
&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;static&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000"&gt; DirectoryInfo ShadowCopyFolder;

        &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;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; Initialize()
        {            
            Directory.CreateDirectory(ShadowCopyFolder.FullName);

            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;clear out plugins)&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000"&gt; (var f &lt;/span&gt;&lt;span style="color: #0000ff"&gt;in&lt;/span&gt;&lt;span style="color: #000000"&gt; ShadowCopyFolder.GetFiles(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;*.dll&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;, SearchOption.AllDirectories))
            {
                f.Delete();
            }            

            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;shadow copy files&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000"&gt; (var plug &lt;/span&gt;&lt;span style="color: #0000ff"&gt;in&lt;/span&gt;&lt;span style="color: #000000"&gt; PluginFolder.GetFiles(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;*.dll&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;, SearchOption.AllDirectories))
            {
                var di &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; Directory.CreateDirectory(Path.Combine(ShadowCopyFolder.FullName, plug.Directory.Name));
                &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; NOTE: You cannot rename the plugin DLL to a different name, it will fail because the assembly name is part if it's manifest
                &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; (a reference to how assemblies are loaded: &lt;/span&gt;&lt;span style="color: #008000; text-decoration: underline"&gt;http://msdn.microsoft.com/en-us/library/yx7xezcf&lt;/span&gt;&lt;span style="color: #008000"&gt; )&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                File.Copy(plug.FullName, Path.Combine(di.FullName, plug.Name), &lt;/span&gt;&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;&lt;span style="color: #000000"&gt;);
            }
            
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; Now, we need to tell the BuildManager that our plugin DLLs exists and to reference them.
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; There are different Assembly Load Contexts that we need to take into account which 
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; are defined in this article here:
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; text-decoration: underline"&gt;http://blogs.msdn.com/b/suzcook/archive/2003/05/29/57143.aspx&lt;/span&gt;&lt;span style="color: #008000"&gt;

            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; * This will put the plugin assemblies in the 'Load' context
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; This works but requires a 'probing' folder be defined in the web.config&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000"&gt; (var a &lt;/span&gt;&lt;span style="color: #0000ff"&gt;in&lt;/span&gt;&lt;span style="color: #000000"&gt;
                ShadowCopyFolder
                .GetFiles(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;*.dll&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;, SearchOption.AllDirectories)
                .Select(x &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;  AssemblyName.GetAssemblyName(x.FullName))
                .Select(x &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; Assembly.Load(x.FullName)))
            {
                BuildManager.AddReferencedAssembly(a);
            }

            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; * This will put the plugin assemblies in the 'LoadFrom' context
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; This works but requires a 'probing' folder be defined in the web.config
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; This is the slowest and most error prone version of the Load contexts.            
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;foreach (var a in
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;    ShadowCopyFolder
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;    .GetFiles("*.dll", SearchOption.AllDirectories)
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;    .Select(plug =&amp;gt; Assembly.LoadFrom(plug.FullName)))
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;{
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;    BuildManager.AddReferencedAssembly(a);
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;}

            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; * This will put the plugin assemblies in the 'Neither' context ( i think )
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; This nearly works but fails during view compilation.
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; This DOES work for resolving controllers but during view compilation which is done with the RazorViewEngine, 
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; the CodeDom building doesn't reference the plugin assemblies directly.
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;foreach (var a in
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;    ShadowCopyFolder
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;    .GetFiles("*.dll", SearchOption.AllDirectories)
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;    .Select(plug =&amp;gt; Assembly.Load(File.ReadAllBytes(plug.FullName))))
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;{
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;    BuildManager.AddReferencedAssembly(a);
            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;}&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;
        }
    }
}
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:08:09 Z</pubDate>
      <a10:updated>2023-03-23T15:08:09Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1250</guid>
      <link>https://shazwazza.com/post/using-metadata-with-mef-in-medium-trust/</link>
      <category>ASP.Net</category>
      <category>Umbraco</category>
      <title>Using metadata with MEF in Medium Trust</title>
      <description>&lt;p&gt;One of the awesome parts of &lt;a href="http://mef.codeplex.com/" target="_blank"&gt;MEF&lt;/a&gt; is that you can attach metadata to your objects. This allows you to use the new &lt;a href="http://msdn.microsoft.com/en-us/library/dd986615.aspx" target="_blank"&gt;Lazy&amp;lt;T, TMetadata&amp;gt;&lt;/a&gt; object so you can inspect the meta data about an object without instantiating it. In order to attach metadata to an object, you need (should have) some entity that contains properties to support the meta data such as an interface (good tutorial site &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/01/20/mef-for-beginner-metadata-part-8.aspx" target="_blank"&gt;here&lt;/a&gt; ). For example, if you have a class of type &lt;em&gt;MyObjectType&lt;/em&gt; and an interface to store metadata about the class of type &lt;em&gt;IMyMetadata&lt;/em&gt;, you can then resolve/import &lt;em&gt;Lazy&amp;lt;MyObjectType, IMyMetadata&amp;gt;&lt;/em&gt; which will expose a &lt;em&gt;Metadata&lt;/em&gt; property of type &lt;em&gt;IMyMetadata&lt;/em&gt; with the information filled in. You might already be able to tell that a bit of magic is happening behind the scenes since there is no concrete class for &lt;em&gt;IMyMetadata&lt;/em&gt; but MEF has magically found a way to instantiate a class of type &lt;em&gt;IMyMetadata&lt;/em&gt; and fill in the values. This is the problem area if you are running in Medium Trust, you will get a &lt;em&gt;SecurityException&lt;/em&gt; stemming form &lt;em&gt;the System.ComponentModel.Composition.MetadataViewGenerator. &lt;/em&gt;This same issue will occur when using &lt;a href="http://code.google.com/p/autofac/" target="_blank"&gt;Autofac&lt;/a&gt; to register metadata with the &lt;a href="http://code.google.com/p/autofac/wiki/Metadata" target="_blank"&gt;.WithMetadata&lt;/a&gt; extension method.&lt;/p&gt;  &lt;h1&gt;Solution&lt;/h1&gt;  &lt;p&gt;To work around this problem in Medium Trust, you’ll need to create a concrete class to store your metadata in instead of just referencing an interface. You’ll also need to ensure that the constructor of this class takes in one parameter of type &lt;em&gt;IDictionary&amp;lt;string, object&amp;gt;&lt;/em&gt; and using this object you’ll need to manually do the heavy lifting of assigning the values to the properties of this class based on the values in the dictionary. Better yet, you can just make a base class that all your metadata classes can inherit from. In Umbraco v5, we’ve called this abstract class &lt;em&gt;MetadataComposition&lt;/em&gt; just to keep inline with the naming conventions of the MEF namespace:&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:9D7513F9-C04C-4721-824A-2B34F0212519:4925520a-87a3-4a2f-b0c0-b20dddee86cf" class="wlWriterEditableSmartContent"&gt;&lt;pre style=" width: 670px; height: 368px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&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;abstract&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; MetadataComposition
{
    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; constructor, sets all properties of this object based 
    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; on the dictionary values
    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name=&amp;quot;obj&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; MetadataComposition(IDictionary&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; obj)
    {
        var t &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetType();
        var props &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; t.GetProperties();
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (var a &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; obj)
        {
            var p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; props.Where(x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; x.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; a.Key).SingleOrDefault();
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (p &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;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
            {
                p.SetValue(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;, a.Value, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
            }
        }
    }
}&lt;/span&gt;&lt;/div&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;Hope this helps someone!&lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:08:09 Z</pubDate>
      <a10:updated>2023-03-23T15:08:09Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1318</guid>
      <link>https://shazwazza.com/post/mvc-controllers-as-plugins-with-mef-and-autofac/</link>
      <category>ASP.Net</category>
      <category>Umbraco</category>
      <title>MVC Controllers as plugins with MEF and Autofac</title>
      <description>&lt;h2&gt;Disclaimer&lt;/h2&gt;  &lt;p&gt;&lt;em&gt;This blog posts talks about &lt;/em&gt;&lt;a href="http://umbraco.org" target="_blank"&gt;&lt;em&gt;Umbraco&lt;/em&gt;&lt;/a&gt;&lt;em&gt; v5 (Jupiter), however since the state of the codebase is in it’s infancy, the details about Umbraco v5 in this article may not be accurate once Umbraco v5 is released.&lt;/em&gt;&lt;/p&gt;  &lt;h2&gt;Plugins&lt;/h2&gt;  &lt;p&gt;In Umbraco v5 we’re introducing the concept of plugins. Currently in Umbraco, we have the notion of plugins such as Trees, Actions (used on context menus), Data types, etc… Each of these objects is found using a class called TypeFinder to search for specific types in all assemblies that are loaded in the ‘bin’ folder. Though this works, it is definitely not the most efficient approach to plugins. For Umbraco v5, we’re now using &lt;a href="http://mef.codeplex.com/" target="_blank"&gt;MEF&lt;/a&gt; as the plugin framework which is now part of .Net framework 4.&amp;#160; There will be many coming blog posts about the different types of plugins, how they work and how to create them using MEF, but this blog post is about overcoming a small hurdle we encountered when trying to integrate MEF, Autofac and MVC controllers as 3rd party plugins….&lt;/p&gt;  &lt;h2&gt;MVC Controllers as plugins&lt;/h2&gt;  &lt;p&gt;For Umbraco v5, we’re using &lt;a href="http://code.google.com/p/autofac/" target="_blank"&gt;Autofac&lt;/a&gt; as the &lt;a href="http://martinfowler.com/articles/injection.html" target="_blank"&gt;IoC&lt;/a&gt; container which works really well for injecting dependencies into MVC controllers (amongst a ton of other things). Autofac also plays really nicely with MEF through it’s &lt;a href="http://code.google.com/p/autofac/wiki/MefIntegration" target="_blank"&gt;MEF integration&lt;/a&gt; library and requires all of 2 lines of code to get the MEF plugins into our IoC container:&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:9D7513F9-C04C-4721-824A-2B34F0212519:42f265e7-c968-4ff1-a6d7-aef30243b292" class="wlWriterEditableSmartContent"&gt;&lt;pre style=" width: 551px; height: 58px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;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; DirectoryCatalog(
    m_HttpServer.MapPath(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Plugins/Trees&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
builder.RegisterComposablePartCatalog(catalog);&lt;/span&gt;&lt;/div&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;The above code tells Autofac to register all &lt;a href="http://mef.codeplex.com/wikipage?title=Declaring%20Exports&amp;amp;referringTitle=Overview" target="_blank"&gt;exportable&lt;/a&gt; MEF components that are found in all assemblies in the &lt;em&gt;~/Plugins/Trees&lt;/em&gt; folder. In our case, the plugins in this folder are actually MVC Controllers which will get registered in to the IoC container and since we are currently using the &lt;a href="http://code.google.com/p/autofac/wiki/MvcIntegration" target="_blank"&gt;AutofacControllerFactory&lt;/a&gt; for our MVC controller factory, it ‘should’ be able to create the requested controller and inject it’s dependencies because we’ve stuck it in the container.&lt;/p&gt;

&lt;h3&gt;Problem 1&lt;/h3&gt;

&lt;p&gt;So far this is all very easy, but as soon as we want to route a request to this controller we end up with a 404 error stating that the page/controller cannot be found.&amp;#160; The reason for this is because the AutofacControllerFactory inherits from the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultcontrollerfactory%28VS.98%29.aspx" target="_blank"&gt;DefaultControllerFactory&lt;/a&gt; which searches for controllers using the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.compilation.buildmanager.aspx" target="_blank"&gt;BuildManager&lt;/a&gt; which only searches for types registered in the ‘bin’ folder. I was hoping that the AutofacControllerFactory would have also searched within it’s registrations but this turns out to not be the case. (In fact, once Autofac releases it’s MVC3 implementation, it will no longer be shipped with an AutofacControllerFactory and instead be using MVC3’s new DependencyResolver).&lt;/p&gt;

&lt;h3&gt;Solution 1&lt;/h3&gt;

&lt;p&gt;In order for this to work we have to create our own ControllerFactory&amp;#160; (source code at the end of this article) and provide our own implementation for the methods:&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:9D7513F9-C04C-4721-824A-2B34F0212519:7930359f-54bd-4536-b44e-f202b3b6ac6a" class="wlWriterEditableSmartContent"&gt;&lt;pre style=" width: 650px; height: 43px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;IController GetControllerInstance(RequestContext context, Type controllerType)
Type GetControllerType(RequestContext requestContext, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; controllerName)&lt;/span&gt;&lt;/div&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;The GetControllerType implementation does the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Checks if the requested controllerName has already been resolved and exists in our factory’s internal cache&lt;/li&gt;

  &lt;li&gt;If not, try to find the controller by name from the underlying DefaultControllerFactory&lt;/li&gt;

  &lt;li&gt;If not found, search the IoC container’s registrations for the type, &lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;if found, store the reference Type in the factory’s internal cache&lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;

&lt;p&gt;The GetControllerInstance does the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Check if the controllerType has been registered in the factory’s internal cache&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;If so, get the return the resolved IController instance from the container&lt;/li&gt;
  &lt;/ul&gt;

  &lt;li&gt;If not, try to create the controller from the underlying DefaultControllerFactory&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Problem 2&lt;/h3&gt;

&lt;p&gt;The next problem we encountered was that Autofac couldn’t inject dependent objects into the controllers that weren’t registered in the container using the Autofac MEF extensions. A quick &lt;a href="http://groups.google.com/group/autofac/browse_thread/thread/cf73b3bb80469f1" target="_blank"&gt;post&lt;/a&gt; on to the Autofac Google Group and I had my answer (read the post if you want examples)! &lt;/p&gt;

&lt;h3&gt;Solution 2&lt;/h3&gt;

&lt;p&gt;Essentially, if you want to expose objects to MEF in Autofac, you have to explicitly register them in the container with the ‘Exported’ extension method. Example:&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:9D7513F9-C04C-4721-824A-2B34F0212519:2db5c654-2b7e-4343-b579-2a3202ad1d84" class="wlWriterEditableSmartContent"&gt;&lt;pre style=" width: 650px; height: 127px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;register the umbraco settings&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;builder.Register&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;UmbracoSettings&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; UmbracoSettings.GetSettings())
    .As&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;IUmbracoSettings&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: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;ensure it's registered for MEF too&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    .Exported(x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; x.As&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;IUmbracoSettings&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: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;only have one instance ever&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    .SingleInstance(); &lt;/span&gt;&lt;/div&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;h3&gt;Problem 3&lt;/h3&gt;

&lt;p&gt;The last problem was that by default it seems that exported MEF components are instantiated as singletons, meaning that each time you try to resolve a MEF component of a certain type it will always be the exact same instance. MVC really doesn’t like this when it comes to controllers, in fact MVC gives you a very informative error message regarding this and explains that if you are using dependency injection to create controllers to make sure the container is configured to resolve new controller objects, not the same instance.&lt;/p&gt;

&lt;h3&gt;Solution 3&lt;/h3&gt;

&lt;p&gt;All we need to do is add a &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.partcreationpolicyattribute.aspx" target="_blank"&gt;PartCreationPolicyAttribute&lt;/a&gt; to the exported MEF type and set it to CreationPolicy.NonShared which tells the framework to create a new instance each time it is resolved. Example:&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:9D7513F9-C04C-4721-824A-2B34F0212519:62c66697-6342-44eb-9811-bc9e0002b7eb" class="wlWriterEditableSmartContent"&gt;&lt;pre style=" width: 650px; height: 55px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;[Tree(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(ContentTreeController))]
[PartCreationPolicy(CreationPolicy.NonShared)]
&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; ContentTreeController : DemoDataTreeController&lt;/span&gt;&lt;/div&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;h2&gt;UmbracoControllerFactory source&lt;/h2&gt;

&lt;p&gt;Here’s the source code for the custom controller factory, it currently inherits from AutofacControllerFactory but once we upgrade to use the new MVC 3 Autofac implementation, this will simply inherit from DefaultControllerFactory.&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:9D7513F9-C04C-4721-824A-2B34F0212519:e6bd69b7-88a0-4f5c-a698-dd379076a554" class="wlWriterEditableSmartContent"&gt;&lt;pre style=" width: 650px; height: 548px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Web;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Web.Mvc;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Linq;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Web.Routing;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Autofac;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Autofac.Core;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Autofac.Integration.Web;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Autofac.Integration.Web.Mvc;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Collections.Generic;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Autofac.Features.Metadata;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; UmbracoProjects.CMS.Web.Trees.Controllers;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Text.RegularExpressions;

&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt; UmbracoProjects.CMS.Web.Mvc.Controllers
{

    &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; UmbracoControllerFactory : AutofacControllerFactory
    {

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; IContainer m_Container;

        &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;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; m_Locker &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; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;();

        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Used to cache found controllers in the IoC container
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;
&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;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000;"&gt; Dictionary&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;, ServiceTypeCache&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; m_IoCControllerCache &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; Dictionary&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;, ServiceTypeCache&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;private&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; ServiceTypeCache
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; Service Service { &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;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; Type ComponentType { &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: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Initializes a new instance of the &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;see cref=&amp;quot;AutofacControllerFactory&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt; class.
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name=&amp;quot;containerProvider&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;The container provider.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&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; UmbracoControllerFactory(IContainerProvider containerProvider)
            : &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;(containerProvider)
        {
            m_Container &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; containerProvider.ApplicationContainer;
        }

        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Creates the controller based on controller type
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;The context.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name=&amp;quot;controllerType&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;Type of the controller.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;The controller.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; This first checks our IoC service internal cache to see if it exists, if it does, we'll try to resolve the controller
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; from IoC, otherwise we'll try to resolve the controller from the underlying factory
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; IController GetControllerInstance(RequestContext context, Type controllerType)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (context &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;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;throw&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; ArgumentNullException(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;context&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;);

            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;first, check if this service by this type is in our cache&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (m_IoCControllerCache.Where(x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; x.Value.ComponentType.Equals(controllerType)).Any())
            {
                var controllerService &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; m_IoCControllerCache.Where(x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; x.Value.ComponentType.Equals(controllerType)).SingleOrDefault().Value.Service;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; controller;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (m_Container.TryResolveService(controllerService, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;out&lt;/span&gt;&lt;span style="color: #000000;"&gt; controller))
                {
                    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;if the controller is created by MEF, then resolve&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (controller &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;is&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.ComponentModel.Composition.Primitives.Export)
                    {
                        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; (IController)((System.ComponentModel.Composition.Primitives.Export)controller).Value;
                    }
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (controller &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;is&lt;/span&gt;&lt;span style="color: #000000;"&gt; IController)
                    {
                        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; (IController)controller;
                    }                 
                }
                
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;throw&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; HttpException(&lt;/span&gt;&lt;span style="color: #800080;"&gt;404&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;.Format(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Controller type &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&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: #000000;"&gt; controllerType &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: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt; could not be resolved&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        controllerService,
                        controllerType.FullName,
                        context.HttpContext.Request.Path));
            }

            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;otherwise, try to create from the underlying factory&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;.GetControllerInstance(context, controllerType);
        }

        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Finds a controller type based on it's name. 
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name=&amp;quot;requestContext&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name=&amp;quot;controllerName&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; This searches using the DefaultControllerFactory's implementation and
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; also searches the IoC container for registered types since types that are registered in the container 
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; may exist outside the bin folder
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; Type GetControllerType(RequestContext requestContext, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; controllerName)
        {
            var controllerKeyName &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; controllerName.ToUpper();

            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;first, check if this is already in our internal cache&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (m_IoCControllerCache.ContainsKey(controllerKeyName))
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; m_IoCControllerCache[controllerKeyName].ComponentType;
            }

            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;next, try to resolve it from the underlying factory&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            var type &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;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;.GetControllerType(requestContext, controllerName);

            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;if the controller can't be resolved by name using the standard method, then we should check our container&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (type &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;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
            {   
                                
                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;we need to search the registered components in IoC for a match                &lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt;(var reg &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; m_Container.ComponentRegistry.Registrations) 
                {
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (var s &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; reg.Services)
                    {
                        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;match namespaces/classe that then end with &amp;quot;controllerName + Controller&amp;quot;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Regex.IsMatch(s.Description, &lt;/span&gt;&lt;span style="color: #800000;"&gt;@&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;(?:\w|\.)+\.&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&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: #000000;"&gt; controllerName &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: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Controller$&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, RegexOptions.Compiled &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; RegexOptions.IgnoreCase))
                        {
                            var controller &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; m_Container.ResolveService(s);
                            var cType &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; controller.GetType();
                            
                            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;add to the internal cache&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&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: #000000;"&gt;m_IoCControllerCache.ContainsKey(controllerKeyName))
                            {
                                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;lock&lt;/span&gt;&lt;span style="color: #000000;"&gt; (m_Locker)
                                {
                                    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;double check&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&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: #000000;"&gt;m_IoCControllerCache.ContainsKey(controllerKeyName))
                                    {
                                        m_IoCControllerCache.Add(controllerKeyName, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ServiceTypeCache() { Service &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s, ComponentType &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cType });
                                    }
                                }
                            }
                            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; cType;
                        }
                    }
                }                
            }

            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; type;
        }      
      
    }
}
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:08:09 Z</pubDate>
      <a10:updated>2023-03-23T15:08:09Z</a10:updated>
    </item>
  </channel>
</rss>