There’s quite a little bit of boiler plate code that is required to be written to get this all working so I’m writing it here so we can all learn from it and use it.
Reference StructureMap in your MVC3 solution.
In your Global.asax file in the Application_Start method, write a line to call a yet-undefined method called “ContainerStrapper.BootStructureMap();”. This is where the whole IoC gets injected and is an absolute requirement.
This container strapper contains all your concrete mappings to interfaces across the entire scope of the project.
public static class ContainerStrapper
{
public static void BootStructureMap()
{
IContainer container = new Container(x =>
{
// Controller and Filter
x.For<IControllerActivator>().Use<StructureMapControllerActivator>();
x.For<IFilterProvider>().Use<StructureMapFilterProvider>();
// Constructor Dependencies
x.For<IGenericRepository>().Use<SomeSpecificRepository>();
x.For<IFooManager>().Use<FooManager>();
x.For<IClock>().Use<SystemClock>();
// Property Dependencies
x.SetAllProperties(p => p.OfType<IGenericRepository>());
x.SetAllProperties(p => p.OfType<IFooManager>());
});
DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
}
}
Next you will need to create a structuremap controller activator as referenced in the first line of that container mapping we just created.
public class StructureMapControllerActivator : IControllerActivator
{
public StructureMapControllerActivator(IContainer container)
{
_container = container;
}
private IContainer _container;
public IController Create(RequestContext requestContext, Type controllerType)
{
return _container.GetInstance(controllerType) as IController;
}
}
…and also a StructureMapFilterProvider:
public class StructureMapFilterProvider : FilterAttributeFilterProvider
{
public StructureMapFilterProvider(IContainer container)
{
_container = container;
}
private IContainer _container;
public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
var filters = base.GetFilters(controllerContext, actionDescriptor);
foreach (var filter in filters) {
_container.BuildUp(filter.Instance);
}
return filters;
}
}
and lastly we make a StructureMapDependencyResolver:
public class StructureMapDependencyResolver : IDependencyResolver
{
public StructureMapDependencyResolver(IContainer container)
{
_container = container;
}
private IContainer _container;
public object GetService(Type serviceType)
{
object instance = _container.TryGetInstance(serviceType);
if (instance == null && !serviceType.IsAbstract)
{
_container.Configure(c => c.AddType(serviceType, serviceType));
instance = _container.TryGetInstance(serviceType);
}
return instance;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _container.GetAllInstances(serviceType).Cast<object>();
}
}
You’re all done and ready to go
To inject dependencies in to your controllers, put the interfaces as arguments in the controller constructor and set them as private variables if you need them in your actions
Comments