[pMixins]

A lightweight open source Mixin and AOP framework for C#


Dependency Injecting Mixins

Dependency Injection is a powerful principle for creating loosely couple, maintainable and testable code. And [pMixins] supports it!

You can configure [pMixins] to use Dependency Injection when creating instances of Mixin and Interceptors / Aspects. Under the hood, [pMixins] uses the DefaultMixinActivator (via the MixinActivatorFactory) to create Mixin instances. The DefaultMixinActivator in turn uses Activator.CreateInstance .

You can create a custom IMixinActivator that hooks into a Dependency Injection framework. There is a issue in GitHub to provide this for common DI frameworks, but for now it's a manual process.

Once you have a custom IMixinActivator wire it into the MixinActivatorFactory and you're done. So let's see this in action.

First let's define a new interface, IDependency:

public interface IDependency
{
   string Name {
      get;
   }
}

And a Mixin that consumes an IDependency:

public class DependencyInjectionMixin
{
   private readonly IDependency _dependency;
   public DependencyInjectionMixin(IDependency dependency)
   {
      _dependency = dependency;
   }
   public string DependencyName {
      get {
         return _dependency.Name;
      }
   }
}

And let's get our Target definition out of the way. Notice, there's nothing special here:

[pMixin(Mixin = typeof(DependencyInjectionMixin))]
public partial class DependencyInjectionMixinExample
{
}

Finally, we'll need a concrete implementation of IDependency for our example to work:

public class Dependency : IDependency
{
   public string Name {
      get {
         return "DI Example!";
      }
   }
}

Now that we have the basics out of the way, let's create our custom IMixinActivator:

public class DependencyInjector : IMixinActivator
{
   public T CreateInstance<T>(params object[] constructorArgs)
   {
      if(typeof(DependencyInjectionMixin).IsAssignableFrom(typeof(T))) {
         constructorArgs = constructorArgs.Union(new object[] {
            new Dependency()
         }).ToArray();
      }
      return new DefaultMixinActivator().CreateInstance<T>(constructorArgs);
   }
}

The first this to notice is DependencyInjector implements IMixinActivator. Moving on, this example only deals with the DependencyInjectionMixin we created earlier. In a real world scenario, you'd probably wanted to cover many more cases or hook into a proper DI framework.

Another important thing to note is the parameter constructorArgs. [pMixins] will pass in objects required by certain wrappers (predominantly references to the Target ) so it is necessary to ensure that these parameters are passed along to objects being created. Finally, DependencyInjector makes use of the DefaultMixinActivator, which is not required, but is perfectly fine.

So now let's test the code to make sure Dependency Injection is working:

[TestFixture]
public class DependencyInjectionMixinExampleTest
{
   [TestFixtureSetUp]
   public void MainSetup()
   {
      MixinActivatorFactory.SetCurrentActivator(new DependencyInjector());
   }
   [TestFixtureTearDown]
   protected void Cleanup()
   {
      MixinActivatorFactory.SetCurrentActivator(new DefaultMixinActivator());
   }
   [Test]
   public void CanCallActivator()
   {
      Assert.AreEqual("DI Example!", new DependencyInjectionMixinExample().DependencyName);
   }
}

The big take away from DependencyInjectionMixinExampleTest is that it registers our custom IMixinActivator in the MainSetup method. This method runs before CanCallActivator, so we know it is wired in.

The Cleanup method is not strictly necessarily. It cleans up the working environment by restoring the default IMixinActivator to make sure this doesn't accidentally impact any other tests. In a real world scenario, you wouldn't need to restore DefaultMixinActivator.


Download the source for this and all other recipes Here!