Reader Level:
ARTICLE

Introduction to Structure Map

Posted by Dhana Lakshmi Articles | ASP.NET MVC September 01, 2010
This article provides a basic idea about structure map for Test Driven Development.
  • 0
  • 0
  • 27123

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
  1. Dependency Injection is an important pattern for creating classes that are easier to unit test in isolation 
  2. Promotes loose coupling between classes and subsystems 
  3. Adds potential flexibility to a codebase for future changes 
  4. Can enable better code reuse 
  5. The implementation is simple and does *not* require a fancy DI tool
Different Types of Injections are
  1. Constructor Injection
  2. Setter Injection
  3. Interface Injection
  4. 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
  1. Castle Windsor
  2. Unity
  3. 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.
  1. Add Reference to Structure Map
  2. Add Structure Map configuration
  3. Register with the Structure Map Registry
  4. Controller Factory for Structure Map.
  5. 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:
  1. PerRequest - The default operation.  A new instance will be created for each request.
  2. Singleton - A single instance will be shared across all requests
  3. ThreadLocal - A single instance will be created for each requesting thread.  Caches the instances with ThreadLocalStorage.
  4. HttpContext - A single instance will be created for each HttpContext.  Caches the instances in the HttpContext.Items collection.
  5. 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

COMMENT USING

Trending up