Implementing Plug-Ins with a DI Container

If you are building a highly extensible application, the right answer these days seems to be to look into MEF. It is a very flexible approach to extensibility and plug ins that works for 3.5 and will become part of the .NET Framework in 4.0.

However, sometimes you just need a simple plug in capability to load some components provided by others. If there is any chance those plug ins will depend on each other and need to talk to each other, bite the bullet and learn and use MEF. But if they just need to be loaded up and called, you can use a simple factory to get the job done. About 4 years ago, I put together a little sample of doing this with a generic factory class here.

A similar requirement came up with a customer this week, but with one twist: we were already using a DI container (Unity) and the plug ins that were going to load were going to have dependencies on some objects and services that the DI container already knew about.

Since the container is really a generic factory itself, I decided to put together a little sample of using Unity as a plug-in factory and thought I would share it here.

Defining the Plug-ins

The first step to a plug-in architecture is to define the common interface(s) that the plug-ins themselves will implement. Say you have this interface definition in a common library:

publicinterface IPlugIn { void DoSomething(); }

Then you define some implementations of that interface in other class libraries (the plug in libraries): publicclass PlugIn1 : IPlugIn { public PlugIn1(ILogger logger) { } publicvoid DoSomething() { Console.WriteLine("PlugIn1 called"); } } Note that this plug in has a dependency on some service (ILogger) that our DI container will know about. #### Using the Container As the Plug-In Factory Now all you need to do is use the ability to configure the Unity container through a config file to have the construction of those plug ins loosely coupled from the code. Define the config info to configure the container with the plug in types, as well as the dependent types:  <configuration><configSections><sectionname="unity"type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>configSections><unity><typeAliases><typeAliasalias="singleton"type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity"/>typeAliases><containers><container><types><typetype="Common.IPlugIn, Common"mapTo="PlugIns.PlugIn1, PlugIns"name="PlugIn1"/><typetype="Common.IPlugIn, Common"mapTo="PlugIns.PlugIn2, PlugIns"name="PlugIn2"/><typetype="SomeDependencyLibrary.ILogger, SomeDependencyLibrary"mapTo="SomeDependencyLibrary.Logger, SomeDependencyLibrary"><lifetimetype="singleton"/>type>types>container>containers>unity>configuration> Then just configure the container and resolve the plug-ins through a call to ResolveAll: IUnityContainer container = new UnityContainer(); UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); section.Containers.Default.Configure(container); IEnumerable plugIns = container.ResolveAll(); foreach (IPlugIn plugin in plugIns) { plugin.DoSomething(); }

And viola. you have a simple plug-in factory using the container.