Before getting into the topic, a little intro about IOC and DIP.
Dependency Injection Principle (DIP)
Dependency Injection is very advantageous for doing Test Driven Development.
Why DIP
- Dependency Injection is an important pattern for creating classes that are easier to unit test in isolation
- Promotes loose coupling between classes and subsystems
- Adds potential flexibility to a codebase for future changes
- Can enable better code reuse
- The implementation is simple and does *not* require a fancy DI tool
Different Types of Injections are
- Constructor Injection
- Setter Injection
- Interface Injection
- Service Locator
IOC (Inversion of Control)
IOC is ways to achieve DIP. IOC is a great way to break the dependencies between classes and promote loose coupling. IOC is vital for Test Driven Development.
Some of the ways to achieve Dependency Injection are
- Castle Windsor
- Unity
- Structure Map.
It supports Setter and Constructor Injection.
Now we will look into the steps to configure Structure Map into our application.
- Add Reference to Structure Map
- Add Structure Map configuration
- Register with the Structure Map Registry
- Controller Factory for Structure Map.
- Call Structure Map in Global.ascx.
Step 1: Add Reference to Structure Map
Add Reference to StructureMap.dll.
You can download Structure Map from http://sourceforge.net/projects/structuremap/
Step 2: Add Structure Map Configuration
using StructureMap;
using StructureMap.Configuration.DSL;
using StructureMap.Configuration;
using StructureMap.Pipeline;
public class ServiceRegistry : Registry
{
protected override void configure()
{
ForRequestedType<IUserService>()
.TheDefaultIsConcreteType<UserService>();
ForRequestedType<ISearchRepository>()
.TheDefaultIsConcreteType<SearchRepository>();
}
}
public class DBServiceRegistry:Registry
{
protected override void configure()
{
ForRequestedType<DBDataContext >()
.TheDefaultIs(() => new DBDataContext())
.CacheBy(InstanceScope.Hybrid);
}
}
The above configuration of Structure Map will inject UserService when there is a request to IUserService.
Similarly it will inject SearchRepository when it finds a request to ISearchRepository.
Types of Instance Scoping Provided by Structure Map:
- PerRequest - The default operation. A new instance will be created for each request.
- Singleton - A single instance will be shared across all requests
- ThreadLocal - A single instance will be created for each requesting thread. Caches the instances with ThreadLocalStorage.
- HttpContext - A single instance will be created for each HttpContext. Caches the instances in the HttpContext.Items collection.
- Hybrid - Uses HttpContext storage if it exists, otherwise uses ThreadLocal storage
Step 3: Register with Structure Map Registry
Using StructureMap;
public static class Bootstrapper
{
public static void ConfigureStructureMap() {
StructureMapConfiguration.AddRegistry(new DBServiceRegistry());
StructureMapConfiguration.AddRegistry(new ServiceRegistry ());
}
}
Note: You could use Step 2 and Step 3 classes in a Single File Named Bootstrapper.cs. This file could be located at the Folder which has Global.asax.
Step 4: Controller Factory For Structure Map
Using StructureMap;
public class StructureMapControllerFactory : DefaultControllerFactory {
protected override IController GetControllerInstance(Type controllerType) {
try {
return ObjectFactory.GetInstance(controllerType) as Controller;
}
catch (StructureMapException) {
System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave());
throw;
}
}
The controller factory is responsible for creating controller instances. We extend the built in default controller factory with our own factory for working StructureMap with ASP.NET MVC .
Note: This file named StructuremapControllerFactory.cs could be located in the Controller Folder.
Step 5: Modify Global.asax
protected void Application_Start() {
RegisterRoutes(RouteTable.Routes);
//Configure StructureMapConfiguration
Bootstrapper.ConfigureStructureMap();
//Set current Controller factory as StructureMapControllerFactory
ControllerBuilder.Current.SetControllerFactory( new myFinance.Web.Controllers.StructureMapControllerFactory()
);
}
The above code will set our controller factory and configure StructureMap configuration when our ASP.NET MVC application is started.
Hope this article will give a basic idea...
Happy Coding