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
To know more about DIP go to http://codebetter.com/blogs/jeremy.miller/archive/2005/10/06/132825.aspx
IOC (inversion of control)
IOC is a way 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.
If interested, click http://codebetter.com/blogs/jeremy.miller/archive/2005/09/20/132290.aspx
To achieve dependency injection
Some of the ways to achieve Dependency Injection are
- Castle Windsor
- Unity
- Structure Map.
In this article, we are going to dig into the Structure Map. It is an open-source Dependency Injection framework for .Net. Jeremy D Miller (blog:http://codebetter.com/blogs/jeremy.miller/default.aspx ) is the creator of 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
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
- Thread local: A single instance will be created for each requesting thread. Caches the instances with ThreadLocalStorage.
- Http context: 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 the 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;
using System;
using System.Web.Mvc;
using System.Web.Routing;
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