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 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.
If interesting, click
http://codebetter.com/blogs/jeremy.miller/archive/2005/09/20/132290.aspx
Some of the ways to achieve Dependency Injection are
- Castle Windsor
- Unity
- Structure Map.
In this article we are going to dig into 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;
usingStructureMap.Configuration.DSL;
usingStructureMap.Configuration;
usingStructureMap.Pipeline;
publicclass ServiceRegistry :Registry
{
protected overridevoid configure()
{
ForRequestedType<IUserService>()
.TheDefaultIsConcreteType<UserService>();
ForRequestedType<ISearchRepository>()
.TheDefaultIsConcreteType<SearchRepository>();
}
}
publicclass DBServiceRegistry:Registry
{
protected overridevoid 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 staticvoid ConfigureStructureMap() {
StructureMapConfiguration.AddRegistry(newDBServiceRegistry());
StructureMapConfiguration.AddRegistry(newServiceRegistry ());
}
}
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 overrideIController GetControllerInstance(TypecontrollerType) {
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