Dependency Injection with Structured Map in MVC 3

Regarding to my previous post – How to implement DI with Unity 2.0, to implement DI with structured map is very similar.

1. Download Structured Map from Gtihub, https://github.com/structuremap/structuremap/downloads and reference StructuredMap to your project.

2. Create a DependencyResolver class and implement interface IDependencyResolver

public class StructureMapDependencyResolver : IDependencyResolver
{
readonly IContainer _container;

public StructureMapDependencyResolver(IContainer container)
{
_container = container;

// TODO: if you haven't registered necessary interfaces somewhere else, you'll need to do so here.
}

public object GetService(Type serviceType)
{
if (serviceType.IsClass)
{
return GetConcreteService(serviceType);
}
else
{
return GetInterfaceService(serviceType);
}
}

private object GetConcreteService(Type serviceType)
{
try
{
// Can't use TryGetInstance here because it won’t create concrete types
return _container.GetInstance(serviceType);
}
catch (StructureMapException)
{
return null;
}
}

private object GetInterfaceService(Type serviceType)
{
return _container.TryGetInstance(serviceType);
}

public IEnumerable<object> GetServices(Type serviceType)
{
return _container.GetAllInstances(serviceType).Cast<object>();
}
}

public class StructureMapControllerActivator : IControllerActivator
{
private readonly IContainer _container;

public StructureMapControllerActivator(IContainer container)
{
_container = container;
}

public IController Create(RequestContext requestContext, Type controllerType)
{
return _container.GetInstance(controllerType) as IController;
}
}

3. Create a class StructurMapContainer with a static method for registering the our dependencies, and register the unity container as the service locator for the MVC application.

Here is an example of registering a SomeService type to the unity container. Of course you will need to write the implementaton of SomeService and implement ISomeService.

public class StructurMapContainer
{
public static IContainer InitContainer()
{
ObjectFactory.Initialize(x =>
{
x.For<IControllerFactory>().Use<DefaultControllerFactory>();
x.For<IControllerActivator>().Use<StructureMapControllerActivator>();
x.For<ISomeService>().Use<SomeService>();
});

return ObjectFactory.Container;
}
}

4. In the Global.asax.cs file, we will call the StructurMapContainer.InitContainer() method.

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);

DependencyResolver.SetResolver(new StructureMapDependencyResolver(StructurMapContainer.InitContainer()));
}

5. Resolving dependencies, to modify HomeController.cs and add a constructor with dependent services


public class HomeController : Controller
{
    private ISomeService _service;
    public HomeController(ISomeService service)
    {
        _service = service;
    }
}

6. Alternatively, you can add the SomeService as a property of HomeController with Dependency attribute.


[Dependency]

public ISomeService SomeService {get;set;}

Advertisements