Tuesday, May 22, 2012

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.

No comments: