Friday, September 6, 2013

Using IoC for Runtime Plug-ins

If you are already using an IoC container in your code it can be easier to leverage it to create a plug-in model. (Instead of using a plug-in framework like MEF - which is still valid, but you may not want to introduce another similar paradigm into your code).


You'll need to add the following to the app.config so that plug-in DLL's will be in the probing path.
 

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing privatePath=".\Plugin" />
    </assemblyBinding>
</runtime>



This is where the plug in DLLs will be saved at runtime. In your composition root the plug-ins assemblies will need to be loaded into the AppDomain so the IoC container can find the plug in types.

public class AssemblyMetadata
{
    public string FileName { get; set; }
   
    public string Path { get; set; }
}

public class PlugInAssemblyLoader
{
    public void DiscoverAssembliesInPlugInFolder(string path, Predicate<AssemblyMetadata> assemblyFilter)
    {
        if (!File.Exists(path))
        {
            return;
        }

        var assemblies = Directory.GetFiles(path).Where(f => Path.GetExtension(f) == ".dll").Select(f => new AssemblyMetadata {FileName = Path.GetFileName(f), Path = f});
        assemblies = assemblies.Where(a => assemblyFilter(a));
        foreach (var assemblyFile in assemblies)
        {
            Assembly.LoadFile(assemblyFile.Path);
        }
       
        LoadAssembliesIntoAppDomain(discoveredAssemblies);
    }
}

public class CompositionRoot
{
    public void MapTypes()
    {
        // Other type registrations with your IoC container...omitted...
       
        // Load any (if any) plugin libraries into memory
        string plugInLibraryLocation = AppDomain.CurrentDomain.BaseDirectory + @"\Plugin"; // Or look up from app.config etc
        new PlugInAssemblyLoader().DiscoverAssembliesInPlugInFolder(plugInLibraryLocation, metadata => metadata.FileName.StartsWith("MyCompany"));
       
        // Be sure to trigger loading app.config registrations for your IoC container. This is where your plugins will be registered.


        // Plugin types could be replacement for standard types necessary in the application, or they could be optional plugins (ie additional filters e
    }
}




No comments:

Post a Comment