Thursday, December 23, 2010

Creating instances dynamically within a layer that uses dependency injection and an IOC container

In a project where I use dependency injection in the business layer together with an IOC container, I had a need to create instances of a type dynamically from a string value, within the business layer itself. One way to do this would be to use reflection, however since the type to create an instance of is decided one layer up (here: service layer), this is not possible. The way I ended up doing it was to inject an instance of a type that implements an interface with a Resolve method, where the type of this instance is defined in the service layer.

Class diagram:

Class diagram

Walkthrough:

1) Created an interface in the business layer:


public interface IInstanceManager
{
 T Resolve(string type);
}

2) Created a new class in the service layer that implements the IInstanceManager interface:


public class InstanceManager : IInstanceManager
{
 public T Resolve(string type)
 {
  var typeInstance = Type.GetType(type);

  if (typeInstance == null)
   throw new Exception(string.Format("Type {0} was not found", type));

  return (T) _container.Resolve(typeInstance);
 }
}

3) Registered the InstanceManager with the IOC container (here: Castle Windsor):


_container.Register(Component.For().ImplementedBy());

4) Modified the class that needed to create instances dynamically to accept and use an instance of a type implementing IInstanceManager:


public class ClassA : IClassA
{
 private IInstanceManager _instanceManager;

 public ClassA(IInstanceManager instanceManager)
 {
  _instanceManager = instanceManager;
 }

 public void DoSomethingOnA()
 {
  var instance = _instanceManager.Resolve("ISomeTypeThatImplementsIClassB");
  instance.DoSomethingOnB();
 }
}