Introduction to Structure Map

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

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

  1. Castle Windsor
  2. Unity
  3. 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.

  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

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. Thread local: A single instance will be created for each requesting thread. Caches the instances with ThreadLocalStorage.
  4. Http context: 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 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


Similar Articles