Dependency Injection (DI) was also supported by classic ASP.NET MVC but there was no framework-level dependency injection like in ASP.NET Core. In this blog post I will show how to use Structuremap for dependency injection in ASP.NET MVC applications and how to resolve dependencies using built-in components in classes that doesn’t support dependency injection.

Legacy warning! The code here and solutions are for classic ASP.NET MVC. If you are working on legacy application written on it and you need to introduce dependency injection there or you need to get rid of ObjectFactory class of old Structuremap then this post is for you. In this post I stay in context of legacy app I’m working on and I don’t want to introduce any big changes to code base.

As long as we work in Application class or controllers things are quiet easy. At application class we create DI container, configure it and then set up controller factory that we introduce to ASP.NET MVC.

But there are ASP.NET and ASP.NET MVC components that doesn’t support dependency injection. Some examples:

  • layout pages and views
  • membership and roles providers
  • controller attributes

There’s no straightforward way to make those things use dependency injection like we want. There was ObjectFactory class in Structuremap but it is deprecated. As a last option we can use Service Locator pattern (once pattern but now anti-pattern). It provides us with static instance that resolves dependencies for us.

But let’s get to dependency injection step by step.

Using Structuremap for dependency injection

I am long time user of Structuremap. It is DI/IoC container that supports assembly scanning and dependency definition registries. Registries are simple classes where containers are configured.

Here’s the primitive example of Structuremap registry.

public class MyRegistry : Registry
{
    public MyRegistry()
    {
        For<IDataMapper>().Use<NHibernateMapperSession>()
                          .LifecycleIs<ThreadLocalStorageLifecycle>();

        For<ILogger>().Use<NLogWrapper>()
                      .LifecycleIs<ThreadLocalStorageLifecycle>();

        For<IInvoiceGenerator>().Use<InvoiceGenerator>()
                                .LifecycleIs<ThreadLocalStorageLifecycle>();
    }
}

And here’s how Structuremap containers are configured (scanning is also possible).

var container = new Container(x =>
{
    x.AddRegistry<MyRegistry>();
    x.AddRegistry<SomeOtherRegistry>();
});

If instance is needed then it’s easy to get it from container.

var logger = container.GetInstance<ILogger>();

It’s all nice but it’s not enough to get dependency injection to classic ASP.NET MVC. We need some more pieces.

#architecture/design/patterns #asp.net

Using Structuremap in legacy ASP.NET MVC applications
1.45 GEEK