How to use StructureMap for Dependency Injection in ASP.NET MVC application?

Do you C-Sharp?
Do you C-Sharp?

Recently, I published some posts that covers very important concepts like when to use Dependency Inversion PrincipleUnit of WorkRepository design patterns in application. I recommend you to read these posts if you are new to these concepts. In this post, I’ll tell you how to use StructureMap for Dependency Injection in ASP.NET MVC application. The same concept can also be applied to ASP.NET Web API application or any other .NET application as well.

Dependency Injection

The basic idea of the Dependency Injection is to have a separate object, an assembler, that populates a field in the lister class with an appropriate implementation for the finder interface.
– Martin Fowler

In other words, the idea behind inversion of control is that, rather than tie the classes in your application together and let classes “new up” their dependencies, you switch it around so dependencies are instead passed in during class construction.

I’ve been using same code in the posts linked above. In my last post to explain Dependency Inversion Principle, I refactored existing code to work with abstractions so that controllers doesn’t need to directly depend on any repository or entity framework detail. Just to recap, the code used in that post looks like following:

public class EventsController : Controller
{
    private readonly IUnitOfWork _unitOfWork;
 
    public EventsController()
    {
        _unitOfWork = new UnitOfWork(new ApplicationDbContext());
    }
 
    public ActionResult Details(int id)
    {
        var event = _unitOfWork.Events.GetEvent(id);
        if (event == null)
            return HttpNotFound();
 
        var viewModel = new EventDetailsViewModel { Event = event };
 
        return View("Details", viewModel);
    }
 
    [Authorize]
    public ActionResult MyEvents()
    {
        var userId = User.Identity.GetUserId();
        var events = _unitOfWork.Events.GetUpcomingEventsByArtist(userId);
 
        return View(events);
    }
}

The highlighted statement above creates an instance of `UnitOfWork` and `ApplicationDbContext` classes. So, this controller is directly dependent on these two classes.

StructureMap Nuget Package

Let’s now add StructureMap to move the responsibility of creating instances of classes from this controller to StructureMap. I’m using ASP.NET MVC version 5, so I’ll be using StructureMap’s MVC5 package for my application using Nuget package manager. Package Manager Console can also be used to install this via following command: `install-package StructureMap.MVC5` and make sure the correct MVC project is selected in the project dropdown option.

Files

Internally it also installs two other packages named as `structuremap` and `structuremap.web`. If the package installation was successful, few files are also added which makes using StructurMap very easy.

File named `StructuremapMVC.cs` is the main file that is added to your application’s `App_Start` folder. This class has two methods named `Start` and `End` that has proper setup and dispose statements respectively. The package has also added few more files under `DependencyResolution` folder and the classes available inside it are used to set up `Start` and `End` methods.

Container & Registry

This `Start` method uses `IoC` class to get a new container which is based of a registry object. Out of the box, StructureMap gives us a default registry named as `DefaultRegistry`.

Let us look at the definition of this class:

public class DefaultRegistry : Registry {

    public DefaultRegistry() {
        Scan(
            scan => {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
     	        scan.With(new ControllerConvention());
            });
        // For<IExample>().Use<Example>();
    }
}

The constructor of this class has designated a policy for scanning assemblies to auto register types. What this means is, if a class named `EventsRepository` implements an interface named `IEventsRepository`, by default this convention helps to inject an instance of the repository class wherever IEventsRepository interface is used – be it in a constructor as a parameter or property inside a class.

For any manual setup use the `For` member for `Registry` class to indicate what type to use for particular type of abstraction.

Constructor & Property Injection

To inject instances of classes to  constructor parameters, no additional steps are required. But for properties, use `SetterProperty` attribute to decorate the property that needs an instance of a class that implements particular interface.

Result

With the above changes, the controller code is now simplified even more as shown below:

public class EventsController : Controller
{
    private readonly IUnitOfWork _unitOfWork;
 
    public EventsController(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }
 
    public ActionResult Details(int id)
    {
        var event = _unitOfWork.Events.GetEvent(id);
        if (event == null)
            return HttpNotFound();
 
        var viewModel = new EventDetailsViewModel { Event = event };
 
        return View("Details", viewModel);
    }
 
    [Authorize]
    public ActionResult MyEvents()
    {
        var userId = User.Identity.GetUserId();
        var events = _unitOfWork.Events.GetUpcomingEventsByArtist(userId);
 
        return View(events);
    }
}

As highlighted above, controller get an instance of `UnitOfWork` class as this class implements `IUnitOfWork` interface. StructureMap is also smart enough to pass an instance of `ApplicationDbContext` class to `UnitOfWork` class constructor as it needs it at the time of construction based on following code:

public class UnitOfWork : IUnitOfWork
{
    private readonly ApplicationDbContext _context;

    public IEventRepository Events { get; private set; }

    public UnitOfWork(ApplicationDbContext context)
    {
        _context = context;
        Events = new EventRepository(context);
    }

    public void Complete()
    {
        _context.SaveChanges();
    }
}

I hope this article explains you clearly how to use StructureMap for Dependency Injection in ASP.NET MVC application. As I said in the beginning, the same concept can also be applied to ASP.NET Web API and other .NET applications. Please subscribe to my blog to read posts on similar topics.

Siddharth Pandey

Siddharth Pandey is a Software Engineer with thorough hands-on commercial experience & exposure to building enterprise applications using Agile methodologies. Siddharth specializes in building, managing on-premise, cloud based real-time standard, single page web applications (SPAs). He has successfully delivered applications in health-care, finance, insurance, e-commerce sectors for major brands in the UK. Other than programming, he also has experience of managing teams, trainer, actively contributing to the IT community by sharing his knowledge using Stack Overflow, personal website & video tutorials.

You may also like...

Advertisment ad adsense adlogger