<?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">1258</guid>
      <link>https://shazwazza.com/post/easily-setup-your-umbraco-installation-with-ioc-dependency-injection/</link>
      <category>Umbraco</category>
      <title>Easily setup your Umbraco installation with IoC / Dependency Injection</title>
      <description>&lt;p&gt;Umbraco supports allowing you to setup and configure any IoC container type that you want to use in your application. For a while now there’s been some sparse documentation on how to achieve this which you can find here: &lt;a title="https://our.umbraco.org/Documentation/reference/using-ioc" href="https://our.umbraco.org/Documentation/reference/using-ioc"&gt;https://our.umbraco.org/Documentation/reference/using-ioc&lt;/a&gt;. As the Umbraco core codebase evolves, sometimes a new non-parameterless constructor is added to a class and sometimes this can confuse an existing container that you’ve setup. For many folks, fixing these errors after upgrading is a trial and error experience until they track down the dependency that is now missing from their container and finally add it.&lt;/p&gt;&lt;p&gt;&lt;a href="https://twitter.com/simonech" target="_blank"&gt;Simone&lt;/a&gt;, a very helpful Umbracian, made a comment on the issue tracker and it’s something that is just so obvious&amp;nbsp; (&lt;a title="http://issues.umbraco.org/issue/U4-9562#comment=67-41855" href="http://issues.umbraco.org/issue/U4-9562#comment=67-41855"&gt;&lt;em&gt;http://issues.umbraco.org/issue/U4-9562#comment=67-41855&lt;/em&gt;&lt;/a&gt;): &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I think the point here is:&amp;nbsp; as user of a framework, I shouldn't need to wire up dependencies for internals of the framework myself. I should only bother about my own dependencies.&lt;br&gt;Maybe Umbraco should ship a small extension method for each of the main IoC container out there which wires up all the internals.&lt;br&gt;Or come with a IoC container out of the box and then everyone using umbraco have to use that one.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;Yes of course this should be done!&lt;/strong&gt;&lt;/p&gt;&lt;h2&gt;A new community project: Our.Umbraco.IoC&lt;/h2&gt;&lt;p&gt;I decided to get the ball rolling with this one and have setup a new Git repo here: &lt;a title="https://github.com/Shazwazza/Our.Umbraco.IoC" href="https://github.com/Shazwazza/Our.Umbraco.IoC"&gt;https://github.com/Shazwazza/Our.Umbraco.IoC&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Currently there are 2 different container configurations committed and working for &lt;a href="https://autofac.org/" target="_blank"&gt;Autofac&lt;/a&gt; and &lt;a href="http://www.lightinject.net/" target="_blank"&gt;LightInject&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;I’ve added some notes to the &lt;a href="https://github.com/Shazwazza/Our.Umbraco.IoC/blob/master/README.md" target="_blank"&gt;readme&lt;/a&gt; on how to contribute and get started so I’m hoping that some folks can create some Pull Requests to add support for more containers. The project is very easy to navigate, it’s got a build script and nuget packages setup. &lt;/p&gt;&lt;h2&gt;Give it a go!&lt;/h2&gt;&lt;p&gt;I’ve published some beta’s to Nuget:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Install-Package Our.Umbraco.IoC.Autofac&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;Install-Package Our.Umbraco.IoC.LightInject&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can actually install both and test each one independently by disabling them by an appSetting:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;add key="Our.Umbraco.IoC.Autofac.Enabled" value="false" /&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;add key="Our.Umbraco.IoC.LightInject.Enabled" value="false" /&amp;gt;&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;If this config key doesn’t exist, it will assume the value is “true”&lt;/p&gt;&lt;h2&gt;Using the container&lt;/h2&gt;&lt;p&gt;Once you’ve got your desired package installed, it will be active in your solution (unless you disable it via config). At this stage you’ll want to add your own bits to the container, so here’s how you do that:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Create a custom Umbraco &lt;em&gt;ApplicationEventHandler &lt;/em&gt;&lt;/li&gt;&lt;li&gt;Override &lt;em&gt;ApplicationInitialized – &lt;/em&gt;we do this in this phase to bind to the container event before the container is built which occurs in the ApplicationStarted phase&lt;/li&gt;&lt;li&gt;Bind to the container event&lt;/li&gt;&lt;li&gt;add any custom services you want to the container&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Here’s a full working example showing various techniques and includes the syntax for both LightInject and Autofac. In this example we’re registering a &lt;em&gt;IServerInfoService&lt;/em&gt; as a request scoped object since it requires an &lt;em&gt;HttpRequestBase&lt;/em&gt;. NOTE: That the basic web objects are already registered in the containers (such as &lt;em&gt;HttpContextBase&lt;/em&gt;, &lt;em&gt;HttpRequestBase&lt;/em&gt;, etc…)&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;
public class MyUmbracoStartup : ApplicationEventHandler
{
    protected override void ApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    {
        //If you are using Autofac:
        AutofacStartup.ContainerBuilding += (sender, args) =&amp;gt;
        {
            //add our own services
            args.Builder.RegisterControllers(typeof(TestController).Assembly);
            args.Builder.RegisterType&lt;serverinfoservice&gt;().As&lt;iserverinfoservice&gt;().InstancePerRequest();
        };

        //If you are using LightInject:
        LightInjectStartup.ContainerBuilding += (sender, args) =&amp;gt;
        {
            //add our own services
            args.Container.RegisterControllers(typeof(TestController).Assembly);
            args.Container.Register&lt;iserverinfoservice  , serverinfoservice=""&gt;(new PerRequestLifeTime());
        };
    }
}

//service
public interface IServerInfoService
{
    string GetValue();
}

//implementation of the service
public class ServerInfoService : IServerInfoService
{
    private readonly HttpRequestBase _umbCtx;

    //requires a request based object so this must be scoped to a request
    public ServerInfoService(HttpRequestBase umbCtx)
    {
        _umbCtx = umbCtx;
    }

    public string GetValue()
    {
        var sb = new StringBuilder();
        sb.AppendLine("Server info!").AppendLine();
        foreach (var key in _umbCtx.ServerVariables.AllKeys)
        {
            sb.AppendLine($"{key} = {_umbCtx.ServerVariables[key]}");
        }
        return sb.ToString();
    }
}

public class TestController : SurfaceController
{
    private readonly IServerInfoService _serverInfoService;

    public TestController(IServerInfoService serverInfoService, UmbracoContext umbCtx): base(umbCtx)
    {
        _serverInfoService = serverInfoService;
    }

    //see /umbraco/surface/test/index to see the result
    public ActionResult Index()
    {
        return Content(_serverInfoService.GetValue(), "text/plain");
    }
}
&lt;/iserverinfoservice,&gt;&lt;/iserverinfoservice&gt;&lt;/serverinfoservice&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Happy holidays!&lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:08:48 Z</pubDate>
      <a10:updated>2023-03-23T15:08:48Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1328</guid>
      <link>https://shazwazza.com/post/custom-assembly-loading-with-aspnet-core/</link>
      <category>ASP.Net</category>
      <title>Custom Assembly loading with Asp.Net Core</title>
      <description>&lt;p&gt;Building a plugin system in Asp.Net Core is a dream compared to previous Asp.Net versions! &lt;/p&gt; &lt;p&gt;In previous versions it was not really feasible to load Assemblies located outside of the /bin folder &lt;em&gt;&lt;u&gt;for a web application&lt;/u&gt;&lt;/em&gt;. &lt;a href="http://shazwazza.com/post/developing-a-plugin-framework-in-aspnet-with-medium-trust/" target="_blank"&gt;I battled with this concept quite a long time ago&lt;/a&gt; and although it’s sort of possible, the notion of having a plugin system that supported loading DLLs from outside of the /bin folder was riddled with hacks/problems and not really supported OOTB. &lt;/p&gt; &lt;p&gt;A large part of the issues has to do with something called an ‘Assembly Load Context’. In traditional .Net there are 3 of these context types: “&lt;strong&gt;Load&lt;/strong&gt;”, “&lt;strong&gt;LoadFrom&lt;/strong&gt;” and “&lt;strong&gt;Neither&lt;/strong&gt;”, &lt;a href="http://blogs.msdn.com/b/suzcook/archive/2003/05/29/57143.aspx" target="_blank"&gt;here’s a very old but very relevant post about these contexts&lt;/a&gt; from Suzanne Cook. In traditional Asp.Net, the “Load” context is used as the default context and it is managed by something called &lt;em&gt;Fusion&lt;/em&gt; (.Net’s normal Assembly Loader/Binder). The problem with this context is that it is difficult to load an assembly into it that isn’t located in &lt;em&gt;Fusion’s &lt;/em&gt;probing paths (i.e. /bin folder). If you load in an Assembly with a different Assembly Load Context and then try to mix it’s Types with the Types from the default context&amp;nbsp; … you’ll quickly see that it’s not going to work. &lt;/p&gt; &lt;h2&gt;The “Neither” context&lt;/h2&gt; &lt;p&gt;Here is the Neither context definition as defined by Suzanne Cook:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;If the user generated or found the assembly instead of Fusion, it's in neither context. This applies to assemblies loaded by Assembly.Load(byte[]) and Reflection Emit assemblies (that haven't been loaded from disk). &lt;/em&gt;&lt;a href="http://blogs.msdn.com/suzcook/archive/2003/09/19/57248.aspx"&gt;&lt;em&gt;Assembly.LoadFile()&lt;/em&gt;&lt;/a&gt;&lt;em&gt; assemblies are also generally loaded into this context, even though a path is given (because it doesn't go through Fusion).&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;In Asp.Net Core (targeting CoreCLR), the default Assembly Load Context is the “Neither” context. This is a flexible context because it doesn’t use &lt;em&gt;Fusion&lt;/em&gt; and&amp;nbsp; it allows for loading assemblies any way that you want - including loading an assembly from a byte array, from a path or by a name. Since all of Asp.Net Core uses this context it means that all of the types loaded in with this context can talk to each other without having the previous Asp.Net problems.&lt;/p&gt; &lt;p&gt;I would assume that Asp.Net Core targeting Desktop CLR would still operate the same as before and still have the 3 types of Assembly Load Context’s … Maybe someone over at Microsoft can elaborate on that one? (David Fowler… surely you know? :)&lt;/p&gt; &lt;h2&gt;Finding referenced plugin assemblies&lt;/h2&gt; &lt;p&gt;In many cases if you create a product that supports plugin types, developers will create plugins for your product and ship them via Nuget. This is a pretty standard approach since it allows developers that are using your product to install plugins from the Nuget command line or from within Visual Studio. In this case plugin types will be found in referenced assemblies to your application and will be automatically loaded. Asp.Net Core has an interface called &lt;em&gt;Microsoft.Extensions.PlatformAbstractions.ILibraryManager&lt;/em&gt; that can be used to resolve your application’s currently referenced ‘Libraries’ (i.e Nuget packages) and then each ‘Library’ returned exposes the Assemblies that it includes. Asp.Net MVC 6 has an even more helpful interface called &lt;em&gt;Microsoft.AspNet.Mvc.Infrastructure.IAssemblyProvider&lt;/em&gt; which returns a list of referenced assemblies that are filtered based on if they are assemblies that reference a subset of MVC assemblies. The default implementation of &lt;em&gt;IAssemblyProvider&lt;/em&gt; (&lt;em&gt;DefaultAssemblyProvider&lt;/em&gt;) is extensible and we can use it to override it’s property &lt;em&gt;ReferenceAssemblies&lt;/em&gt; in order to supply our own product assembly names instead of the MVC ones. This is perfect since this allows us to get a list of candidate assemblies that might contain plugins for your product:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ReferencePluginAssemblyProvider : DefaultAssemblyProvider
{
    &lt;span class="rem"&gt;//NOTE: The DefaultAssemblyProvider uses ILibraryManager to do the library/assembly querying&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; ReferencePluginAssemblyProvider(ILibraryManager libraryManager) : &lt;span class="kwrd"&gt;base&lt;/span&gt;(libraryManager)
    {
    }

    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; HashSet&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; ReferenceAssemblies 
        =&amp;gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; HashSet&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="kwrd"&gt;new&lt;/span&gt;[] {&lt;span class="str"&gt;"MyProduct.Web"&lt;/span&gt;, &lt;span class="str"&gt;"MyProduct.Core"&lt;/span&gt;});
}&lt;/pre&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;now if you want to get a list of candidate assemblies that your application is referencing you could do:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;//returns all assemblies that reference your product Assemblies&lt;/span&gt;
var candidateReferenceAssemblies = referencedPluginAssemblyProvider.CandidateAssemblies;&lt;/pre&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;h2&gt;Finding and loading non-referenced plugin assemblies&lt;/h2&gt;
&lt;p&gt;This is where things get fun since this is the type of thing that wasn’t really very feasible with traditional Asp.Net web apps. Lets say you have a plugin framework where a plugin is installed via your web app, not in Visual Studio and therefore not directly referenced in your project. For this example, the plugin is a self contained collection of files and folders which could consist of: Css, JavaScript, Razor Views, and Assemblies. This plugin model is pretty nice since to install the plugin would mean just dropping the plugin folder into the right directory in your app and similarly&amp;nbsp; to uninstall it you can just remove the folder.&amp;nbsp; The first step is to be able to load in these plugin Assemblies from custom locations. For an example, let’s assume the web app has the following folder structure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;App Root 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;App_Plugins &lt;/strong&gt;&lt;em&gt;&amp;lt;—This will be the directory that contains plugin folders&lt;/em&gt; 
&lt;ul&gt;
&lt;li&gt;MyPlugin1 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;bin &lt;/strong&gt;&lt;em&gt;&amp;lt;—by convention we’ll search for Assemblies in the /bin folder inside of a plugin&lt;/em&gt; 
&lt;li&gt;Views&lt;/li&gt;&lt;/ul&gt;
&lt;li&gt;MyPlugin2 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;bin&lt;em&gt; &lt;/em&gt;&lt;/strong&gt;&lt;em&gt;&amp;lt;—by convention we’ll search for Assemblies in the /bin folder inside of a plugin&lt;/em&gt; 
&lt;li&gt;css&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;li&gt;Views 
&lt;li&gt;&lt;em&gt;wwwroot&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;h3&gt;IAssemblyLoader&lt;/h3&gt;
&lt;p&gt;The first thing we need is an ‘&lt;em&gt;Microsoft.Extensions.PlatformAbstractions.IAssemblyLoader&lt;/em&gt;’, this is the thing that will do the assembly loading into the Assembly Load Context based on an &lt;em&gt;AssemblyName &lt;/em&gt;and a location of a DLL:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DirectoryLoader : IAssemblyLoader
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; IAssemblyLoadContext _context;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; DirectoryInfo _path;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; DirectoryLoader(DirectoryInfo path, IAssemblyLoadContext context)
    {
        _path = path;
        _context = context;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; Assembly Load(AssemblyName assemblyName)
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; _context.LoadFile(Path.Combine(_path.FullName, assemblyName.Name + &lt;span class="str"&gt;".dll"&lt;/span&gt;));
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; IntPtr LoadUnmanagedLibrary(&lt;span class="kwrd"&gt;string&lt;/span&gt; name)
    {
        &lt;span class="rem"&gt;//this isn't going to load any unmanaged libraries, just throw&lt;/span&gt;
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; NotImplementedException();
    }
}&lt;/pre&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;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;h3&gt;IAssemblyProvider&lt;/h3&gt;
&lt;p&gt;Next up we’ll need a custom &lt;em&gt;IAssemblyProvider&lt;/em&gt; but instead of using the one MVC ships with, this one will be totally custom in order to load and resolve the assemblies based on the plugin’s /bin folders. The following code should be pretty straight forward, the &lt;em&gt;CandidateAssemblies&lt;/em&gt; property iterates over each found /bin folder inside of a plugin’s folder inside of App_Plugins. For each /bin folder found it creates a &lt;em&gt;DirectoryLoader &lt;/em&gt;mentioned above and loads in each DLL found by it’s &lt;em&gt;AssemblyName&lt;/em&gt; into the current Assembly Load Context.&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// This will return assemblies found in App_Plugins plugin's /bin folders&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CustomDirectoryAssemblyProvider : IAssemblyProvider
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; IFileProvider _fileProvider;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; IAssemblyLoadContextAccessor _loadContextAccessor;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; IAssemblyLoaderContainer _assemblyLoaderContainer;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; CustomDirectoryAssemblyProvider(
            IFileProvider fileProvider, 
            IAssemblyLoadContextAccessor loadContextAccessor, 
            IAssemblyLoaderContainer assemblyLoaderContainer)
    {
        _fileProvider = fileProvider;
        _loadContextAccessor = loadContextAccessor;
        _assemblyLoaderContainer = assemblyLoaderContainer;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerable&amp;lt;Assembly&amp;gt; CandidateAssemblies
    {
        get
        {
            var content = _fileProvider.GetDirectoryContents(&lt;span class="str"&gt;"/App_Plugins"&lt;/span&gt;);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!content.Exists) &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;break&lt;/span&gt;;
            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var pluginDir &lt;span class="kwrd"&gt;in&lt;/span&gt; content.Where(x =&amp;gt; x.IsDirectory))
            {
                var binDir = &lt;span class="kwrd"&gt;new&lt;/span&gt; DirectoryInfo(Path.Combine(pluginDir.PhysicalPath, &lt;span class="str"&gt;"bin"&lt;/span&gt;));
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (!binDir.Exists) &lt;span class="kwrd"&gt;continue&lt;/span&gt;;
                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var assembly &lt;span class="kwrd"&gt;in&lt;/span&gt; GetAssembliesInFolder(binDir))
                {
                    &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; assembly;
                }
            }
        }
    }

    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// Returns assemblies loaded from /bin folders inside of App_Plugins&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;param name="binPath"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; IEnumerable&amp;lt;Assembly&amp;gt; GetAssembliesInFolder(DirectoryInfo binPath)
    {
        &lt;span class="rem"&gt;// Use the default load context&lt;/span&gt;
        var loadContext = _loadContextAccessor.Default;

        &lt;span class="rem"&gt;// Add the loader to the container so that any call to Assembly.Load &lt;/span&gt;
        &lt;span class="rem"&gt;// will call the load context back (if it's not already loaded)&lt;/span&gt;
        &lt;span class="kwrd"&gt;using&lt;/span&gt; (_assemblyLoaderContainer.AddLoader(
            &lt;span class="kwrd"&gt;new&lt;/span&gt; DirectoryLoader(binPath, loadContext)))
        {
            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var fileSystemInfo &lt;span class="kwrd"&gt;in&lt;/span&gt; binPath.GetFileSystemInfos(&lt;span class="str"&gt;"*.dll"&lt;/span&gt;))
            {
                &lt;span class="rem"&gt;//// In theory you should be able to use Assembly.Load() here instead&lt;/span&gt;
                &lt;span class="rem"&gt;//var assembly1 = Assembly.Load(AssemblyName.GetAssemblyName(fileSystemInfo.FullName));&lt;/span&gt;
                var assembly2 = loadContext.Load(AssemblyName.GetAssemblyName(fileSystemInfo.FullName));
                &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; assembly2;
            }
        }
    }
}&lt;/pre&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;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;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;That’s pretty much it! If you have an instance of &lt;em&gt;CustomDirectoryAssemblyProvider&lt;/em&gt; then you can get Assembly references to all of the assemblies found in App_Plugins:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;//returns all plugin assemblies found in App_Plugins&lt;/span&gt;
var candidatePluginAssemblies = customDirectoryAssemblyProvider.CandidateAssemblies;&lt;/pre&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;h2&gt;Integrating non-referenced plugins/Assemblies with MVC&lt;/h2&gt;
&lt;p&gt;What if you had custom plugin types as MVC Controllers or other MVC types? By default MVC only knows about assemblies that your project has references to based on the &lt;em&gt;DefaultAssemblyLoader&lt;/em&gt;.&amp;nbsp; If we wanted MVC to know about Controllers that exist in a plugin not referenced by your project (i.e. in App_Plugins) then it’s a case of registering a custom &lt;em&gt;IAssemblyProvider&lt;/em&gt; in IoC which will get resolved by MVC. To make this super flexible we can create a custom &lt;em&gt;IAssemblyProvider&lt;/em&gt; that wraps multiple other ones and allows you to pass in a custom &lt;em&gt;referenceAssemblies&lt;/em&gt; filter if you wanted to use this to resolve your own plugin types:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CompositeAssemblyProvider : DefaultAssemblyProvider
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; IAssemblyProvider[] _additionalProviders;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] _referenceAssemblies;

    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// Constructor&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;param name="libraryManager"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;param name="additionalProviders"&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// If passed in will concat the assemblies returned from these &lt;/span&gt;
    &lt;span class="rem"&gt;/// providers with the default assemblies referenced&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;param name="referenceAssemblies"&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// If passed in it will filter the candidate libraries to ones&lt;/span&gt;
    &lt;span class="rem"&gt;/// that reference the assembly names passed in. &lt;/span&gt;
    &lt;span class="rem"&gt;/// (i.e. "MyProduct.Web", "MyProduct.Core" )&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; CompositeAssemblyProvider(
        ILibraryManager libraryManager,
        IAssemblyProvider[] additionalProviders = &lt;span class="kwrd"&gt;null&lt;/span&gt;,
        &lt;span class="kwrd"&gt;string&lt;/span&gt;[] referenceAssemblies = &lt;span class="kwrd"&gt;null&lt;/span&gt;) : &lt;span class="kwrd"&gt;base&lt;/span&gt;(libraryManager)
    {
        _additionalProviders = additionalProviders;
        _referenceAssemblies = referenceAssemblies;
    }

    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// Uses the default filter if a custom list of reference&lt;/span&gt;
    &lt;span class="rem"&gt;/// assemblies has not been provided&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; HashSet&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; ReferenceAssemblies
        =&amp;gt; _referenceAssemblies == &lt;span class="kwrd"&gt;null&lt;/span&gt;
            ? &lt;span class="kwrd"&gt;base&lt;/span&gt;.ReferenceAssemblies
            : &lt;span class="kwrd"&gt;new&lt;/span&gt; HashSet&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(_referenceAssemblies);
    
    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// Returns the base Libraries referenced along with any DLLs/Libraries&lt;/span&gt;
    &lt;span class="rem"&gt;/// returned from the custom IAssemblyProvider passed in&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; IEnumerable&amp;lt;Library&amp;gt; GetCandidateLibraries()
    {
        var baseCandidates = &lt;span class="kwrd"&gt;base&lt;/span&gt;.GetCandidateLibraries();
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (_additionalProviders == &lt;span class="kwrd"&gt;null&lt;/span&gt;) &lt;span class="kwrd"&gt;return&lt;/span&gt; baseCandidates;
        &lt;span class="kwrd"&gt;return&lt;/span&gt; baseCandidates               
            .Concat(
            _additionalProviders.SelectMany(provider =&amp;gt; provider.CandidateAssemblies.Select(
                x =&amp;gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Library(x.FullName, &lt;span class="kwrd"&gt;null&lt;/span&gt;, Path.GetDirectoryName(x.Location), &lt;span class="kwrd"&gt;null&lt;/span&gt;, Enumerable.Empty&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(),
                    &lt;span class="kwrd"&gt;new&lt;/span&gt;[] { &lt;span class="kwrd"&gt;new&lt;/span&gt; AssemblyName(x.FullName) }))));
    }
}&lt;/pre&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;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;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;To register this in IoC you just need to make sure it’s registered after you register MVC so that it overrides the last registered &lt;em&gt;IAssemblyProvider&lt;/em&gt;:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;//Add MVC services&lt;/span&gt;
services.AddMvc();
&lt;span class="rem"&gt;//Replace the default IAssemblyProvider with the composite one&lt;/span&gt;
services.AddSingleton&amp;lt;IAssemblyProvider, CompositeAssemblyProvider&amp;gt;(provider =&amp;gt;
{
    &lt;span class="rem"&gt;//create the custom plugin directory provider&lt;/span&gt;
    var hosting = provider.GetRequiredService&amp;lt;IApplicationEnvironment&amp;gt;();
    var fileProvider = &lt;span class="kwrd"&gt;new&lt;/span&gt; PhysicalFileProvider(hosting.ApplicationBasePath);
    var pluginAssemblyProvider = &lt;span class="kwrd"&gt;new&lt;/span&gt; CustomDirectoryAssemblyProvider(
        fileProvider,         
        PlatformServices.Default.AssemblyLoadContextAccessor,
        PlatformServices.Default.AssemblyLoaderContainer);
    &lt;span class="rem"&gt;//return the composite one - this wraps the default MVC one&lt;/span&gt;
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CompositeAssemblyProvider(
        provider.GetRequiredService&amp;lt;ILibraryManager&amp;gt;(),
        &lt;span class="kwrd"&gt;new&lt;/span&gt; IAssemblyProvider[] {pluginAssemblyProvider});
});&lt;/pre&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Your all set! Now you have the ability to load in Assemblies from any location you want, you could even load them in as byte array’s from an external data source.&amp;nbsp; What’s great about all of this is that it just works and you can integrate these external Assemblies into MVC. &lt;/p&gt;
&lt;p&gt;Some things worth noting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Parts of the assembly loading APIs are changing a bit in Asp.Net Core RC2: &lt;a title="https://github.com/aspnet/Announcements/issues/149" href="https://github.com/aspnet/Announcements/issues/149"&gt;https://github.com/aspnet/Announcements/issues/149&lt;/a&gt; 
&lt;li&gt;The above code doesn’t take into account what happens if you load in the same Assembly from multiple locations. In this case, the last one in wins/is active AFAIK – I haven’t tested this yet but I’m pretty sure that’s how it works. 
&lt;li&gt;You may have some issues if load in the same Assembly more than once from multiple locations if those Assemblies have different strong names, or major versions applied to them – I also haven’t tested this yet&lt;/li&gt;&lt;/ul&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:08:15 Z</pubDate>
      <a10:updated>2023-03-23T15:08:15Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1283</guid>
      <link>https://shazwazza.com/post/registering-custom-components-in-ioc-for-umbraco-5-plugins/</link>
      <category>Umbraco</category>
      <title>Registering custom components in IoC for Umbraco 5 plugins</title>
      <description>&lt;p&gt;Sometimes you might need to add some of your own components to the IoC container in Umbraco 5 for your plugins to function. We’ve made this extremely easy to do and it only requires 2 steps:&lt;/p&gt; &lt;p&gt;Create a custom class that implements &lt;em&gt;Umbraco.Framework.DependencyManagement.IDependencyDemandBuilder . &lt;/em&gt;&lt;strong&gt;Ensure that this class does not have any constructor parameters otherwise it will not work. &lt;/strong&gt;There’s only one method to implement and you can use the containerBuilder parameter to add stuff to the IoC container:&lt;/p&gt;  &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Build(IContainerBuilder containerBuilder, IBuilderContext context);&lt;/p&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;

&lt;p&gt;Next you need to attribute your plugin (i.e. Tree, Editor, Menu Item, Property Editor, Surface Controller, etc….) to tell it which ‘Demand Builder’ to use. Easiest to explain with an example:&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;[DemandsDependencies(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(MyCustomBuilder))]&lt;br&gt;[Tree(&lt;span style="color: #006080"&gt;"4883C970-2499-488E-A963-5204F6C6F840"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"My Tree"&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyCustomTree : TreeController&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;
&lt;p&gt;The above code will ensure that the ‘Demand Builder’ of type MyCustomBuilder will be executed when this plugin is loaded&lt;/p&gt;
&lt;p&gt;Thats it! Now you can add anything you need to the IoC container if you require this for your plugin.&lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:08:08 Z</pubDate>
      <a10:updated>2023-03-23T15:08:08Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1289</guid>
      <link>https://shazwazza.com/post/using-ioc-with-umbraco-mvc/</link>
      <category>ASP.Net</category>
      <category>Umbraco</category>
      <title>Using IoC with Umbraco &amp; MVC</title>
      <description>&lt;p&gt;The question was asked on my post yesterday about the upcoming Umbraco 4.10.0 release with MVC support and whether it is possible to use IoC/Dependency Injection with our implementation. The answer is definitely &lt;strong&gt;yes&lt;/strong&gt;! &lt;/p&gt; &lt;p&gt;One of the decisions we’ve made for the code of Umbraco is to not use IoC in the core. This is not because we don’t like IoC (in fact I absolutely love it) but more because things start to get really messy when not 100% of your developers understand it and use it properly. Since Umbraco is open source there are developers from many walks of life committing code to the core and we’d rather not force a programming pattern on them. Additionally, if some developers don’t fully grasp this pattern this leads to strange and inconsistent code and even worse if developers don’t understand this pattern then sometimes IoC can be very difficult to debug.&lt;/p&gt; &lt;p&gt;This ultimately means things are better for you since we won’t get in the way with whatever IoC framework you choose.&lt;/p&gt; &lt;h2&gt;Which frameworks can i use?&lt;/h2&gt; &lt;p&gt;Theoretically you can use whatever IoC framework that you’d like, though I haven’t tested or even tried most of them I’m assuming if they are reasonable frameworks that work with MVC then you should be fine. I’m an Autofac fan and to be honest I’ve only dabbled in other frameworks so all examples in this post and documentation are based on Autofac. Since we don’t use any IoC, it also means that we are not specifying a &lt;em&gt;DependencyResolver&lt;/em&gt; so you are free to set this to whatever you like (I’d assume that most IoC frameworks would integrate with MVC via the &lt;em&gt;DependencyResolver&lt;/em&gt;).&lt;/p&gt; &lt;h2&gt;How do i do it?&lt;/h2&gt; &lt;p&gt;I chucked up some docs on github &lt;a href="https://github.com/Shandem/Umbraco4Docs/blob/4.8.0/Documentation/Reference/Mvc/using-ioc.md" target="_blank"&gt;here&lt;/a&gt; which I’ll basically just reiterate on this post again with some more points. Assuming that you construct your IoC container in your global.asax, the first thing you’ll have to do is to create this class and make sure it inherits from the Umbraco one (otherwise nothing will work). Then just override OnApplicationStarted and build up your container. Here’s an example (using Autofac):&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// The global.asax class&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyApplication : Umbraco.Web.UmbracoApplication
{
    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnApplicationStarted(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)
    {
        &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnApplicationStarted(sender, e);

        var builder = &lt;span class="kwrd"&gt;new&lt;/span&gt; ContainerBuilder();

        &lt;span class="rem"&gt;//register all controllers found in this assembly&lt;/span&gt;
        builder.RegisterControllers(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(MyApplication).Assembly);

        &lt;span class="rem"&gt;//add custom class to the container as Transient instance&lt;/span&gt;
        builder.RegisterType&amp;lt;MyAwesomeContext&amp;gt;();

        var container = builder.Build();
        DependencyResolver.SetResolver(&lt;span class="kwrd"&gt;new&lt;/span&gt; AutofacDependencyResolver(container));
    }
}&lt;/pre&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;Notice that I’ve also registered a custom class called MyAwesomeContext in to my container, this is just to show you that IoC is working. Of course you can do whatever you like with your own container :) Here’s the class:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyAwesomeContext
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; MyAwesomeContext()
    {
        MyId = Guid.NewGuid();
    }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; Guid MyId { get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set; }
}&lt;/pre&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;Next we’ll whip up a custom controller to hijack all routes for any content item that is of a Document Type called ‘Home’ (there’s documentation on github about hijacking routes too):&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; HomeController : RenderMvcController
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; MyAwesomeContext _myAwesome;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; HomeController(MyAwesomeContext myAwesome)
    {
        _myAwesome = myAwesome;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; ActionResult Index(Umbraco.Web.Models.RenderModel model)
    {
        &lt;span class="rem"&gt;//get the current template name&lt;/span&gt;
        var template = &lt;span class="kwrd"&gt;this&lt;/span&gt;.ControllerContext.RouteData.Values[&lt;span class="str"&gt;"action"&lt;/span&gt;].ToString();
        &lt;span class="rem"&gt;//return the view with the model as the id of the custom class&lt;/span&gt;
        &lt;span class="kwrd"&gt;return&lt;/span&gt; View(template, _myAwesome.MyId);
    }
}&lt;/pre&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;In the above controller, a new instance of &lt;em&gt;MyAwesomeContext&lt;/em&gt; will be injected into the constructor, in the Index action we’re going to return the view that matches the currently routed template and set the model of the view to the id of the custom &lt;em&gt;MyAwesomeContext &lt;/em&gt;object (This is just an example, you’d probably do something much more useful than this).&lt;/p&gt;
&lt;p&gt;We can also do something similar with SurfaceControllers (or any controller you like):&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyTestSurfaceController : SurfaceController
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; MyAwesomeContext _myAwesome;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; MyTestSurfaceController(MyAwesomeContext myAwesome)
    {
        _myAwesome = myAwesome;
    }

    [ChildActionOnly]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult HelloWorld()
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; Content(&lt;span class="str"&gt;"Hello World! Here is my id "&lt;/span&gt; + _myAwesome.MyId);
    }
}&lt;/pre&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;h2&gt;That’s it?&lt;/h2&gt;
&lt;p&gt;Yup, these are just examples of creating controllers with IoC, the actual IoC setup is super easy and should pretty much work out of the box with whatever IoC framework you choose. However, you should probably read the ‘Things to note’ in the &lt;a href="https://github.com/Shandem/Umbraco4Docs/blob/4.8.0/Documentation/Reference/Mvc/using-ioc.md" target="_blank"&gt;documentation&lt;/a&gt; in case your IoC engine of choice does something wacky with the controller factory.&lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:08:08 Z</pubDate>
      <a10:updated>2023-03-23T15:08:08Z</a10:updated>
    </item>
  </channel>
</rss>