Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How To Quickly Set Up Dependency Injection With Autofac

0.00/5 (No votes)
24 Feb 2017 1  
How to quickly set up Dependency Injection with Autofac

Are you confused by Dependency Injection? SOLID principles? Inversion of Control? These concepts get thrown around a lot in our industry. That’s fine if you’re already an expert. But what if you’re not? What if you’ve got limited experience?

Maybe you’ve read about it in a couple of books. Got a grasp of the theory. That’s all well and good. But how does it translate to a real-world application? Why should you even bother with it if you haven’t used it before? You’ve been building websites for years and they work fine without it. What’s the big deal?

Don’t worry, you’re not alone. In this article, we’re going to try and cut through some of the buzzwords and jargon. We’ll aim to understand what role Dependency Injection plays and how it can benefit you. We’ll also look at using a Dependency Injection container (Autofac) and how it helps.

Jargon #1: Design Patterns

Before we start, let’s have a look at some of this jargon. To start with, there’s Dependency Injection (DI). Then there’s Inversion of Control (IoC). These are pretty much the same thing. IoC is a design pattern. It’s the theory behind why we write code in a certain way.

Wait a second though, there’s another buzzword. What’s a design pattern? Well, it’s a way to describe solutions to common problems. As developers and architects, we've come up against the same problems, time after time. You can see that throughout the history of software development. We've solved a lot of these problems the same way, again and again. As soon as we describe the approach and give it a name, a design pattern is born. Now, when we talk to each other about an approach, we can use fewer words to do it. That’s always helpful!

Pattern-tastic developer: You want to use a factory for that...

You: A factory? How does that work then? Google, you are my friend...

Jargon #2: Inversion of Control

Where were we? Ah yes, DI and IoC. So, IoC is a design pattern. What’s it all about, though? Let’s take a look at an example. Here’s a class from this very website. First, we’ll take a look at it without any IoC or DI or anything like that. Then, we’ll see how IoC would affect it. Next, we’ll apply DI to change how it’s organised. Finally, we’ll look at what advantages that gives us. Here’s our class, SignInViewModelFactory. It’s responsible for creating a SignInViewModel:

public class SignInViewModelFactory
{
    public SignInViewModel Create(bool input)
    {
        var logger = new NLogLogger();
        logger.Info("UserDetailsViewModelFactory: Entering Create");
        var userHandler = new UserHandler();
        var user = userHandler.GetCurrentUser();
        return new SignInViewModel
        {
            ShowSignIn = input,
            IsSignedIn = user != null
        };
    }
}

If we look at the Create method, it uses, or depends on, 3 other classes. There’s an NLogLogger, for logging messages via NLog. There’s a UserHandler, which checks if a user is signed in already (amongst other things). Then there’s the SignInViewModel itself. Because our factory depends on these 3 classes, we call them dependencies. At the moment, the factory creates those dependencies. I use the factory in a controller, but the controller doesn’t know about the logger or handler. We’ll see what impact that has in a moment.

Jargon #3: Dependency Injection

Let’s think about what needs to happen if we apply IoC to this class. We’ll be changing (inverting) the control of which class creates the dependencies. Instead of the factory creating them, the controller will be instead. How can it do that? Through Dependency Injection. If we pass in the dependencies, the factory stops needing to care about how to create them. It only needs to care about using them. That makes the Create code much simpler.

If we don’t create the dependencies within the factory, we have to pass them in. We can either create them as properties (property injection), or pass them in via the constructor (constructor injection). I always favour constructor injection. I think it makes the dependencies very clear when you look at the code for a class. If you inject via properties, a dependency gets created when the property is first accessed. If you use the constructor, all dependencies are created when the class is created. Here’s our code with its new constructor:

public class SignInViewModelFactory
{
    private readonly UserHandler userHandler;
    private readonly NLogLogger logger;

    public SignInViewModelFactory(UserHandler userHandler, NLogLogger logger)
    {
        this.userHandler = userHandler;
        this.logger = logger;
    }

    public SignInViewModel Create(bool input)
    {
        logger.Info("UserDetailsViewModelFactory: Entering Create");
        var user = userHandler.GetCurrentUser();
        return new SignInViewModel
        {
            ShowSignIn = input,
            IsSignedIn = user != null
        };
    }
}

View the original article.

Advantage #1: Swap Implementations Around With Ease

Our code’s better, but it’s still not great. We’re not worrying about creating the NLogLogger or UserHandler within our factory now. The trouble is, the factory still has to care that it’s using an NLogLogger. What if we change to Log4Net instead? Or write a custom logger? We’d have to change our code wherever we use the logger. What a pain that might turn out to be.

If we wrap these dependencies with interfaces, then we don’t care which actual logger is being used. As long as the logger has got an Info method, it can be any kind (if you want to get technical, that’s loose coupling right there, but don’t get too hung up on the terminology at this stage). We just need something that does some logging. The factory doesn’t care about what we're using to do our logging. It should be the logger that cares about that. Let’s change our code again to use interfaces:

public class SignInViewModelFactory : IViewModelFactory<bool, SignInViewModel>
{
    private readonly IUserHandler userHandler;
    private readonly ILogger logger;

    public SignInViewModelFactory(IUserHandler userHandler, ILogger logger)
    {
        this.userHandler = userHandler;
        this.logger = logger;
    }

    public SignInViewModel Create(bool input)
    {
        logger.Info("UserDetailsViewModelFactory: Entering Create");
        var user = userHandler.GetCurrentUser();
        return new SignInViewModel
        {
            ShowSignIn = input,
            IsSignedIn = user != null
        };
    }
}

I’ve added an interface to the factory as well, because it uses one in real life. Here’s some further reading about factories:

Advantage #2: Testing

Another big advantage of using interfaces comes when we think about testing. Now, I know that not everyone thinks about or has time/budget/scope to include unit testing in their project. I get that. The thing is, even if you’re not doing it now, there’s a chance you might in the future. If not on your current project, then on a future one. In another job. If you’re already writing code in a testable way, you’re ahead of the game. It’s becoming so important for so many companies now.

As soon as you introduce interfaces into your code, you can write unit tests. You can inject fake versions of your dependencies into your tests and check they get called. You can ignore what happens with the dependencies and check that your code does what it’s supposed to do. In our Create method above, IsSignedIn should be true if the handler retrieves a user. If the handler returns null, IsSignedIn should be false. We don’t care about how the handler gets the user. We’ll write a test somewhere else for that. All we care about is whether the user comes back from the GetCurrentUser call.

Poor Man’s Dependency Injection

So how do we set things up to give us these dependencies? First off, we can use Poor Man’s Dependency Injection. This is where we initialise the dependencies ourselves. For this to work, we need a parameterless constructor within each class. We use the parameterless constructor to initialise the dependencies. Here’s the parameterless constructor for the factory:

public SignInViewModelFactory()
{
    this.userHandler = new UserHandler();
    this.logger = new NLogLogger();
}

Let’s see the controller that uses the factory. We’ll need an extra constructor for that too. If we don’t have one, our application will break, because MVC needs an empty constructor to initialise the controller with. Here’s the SecurityController in question:

public class SecurityController : Controller
{
    private readonly IViewModelFactory<bool, SignInViewModel> viewModelFactory;
    private readonly IMembershipProvider membershipProvider;
    private readonly ILogger logger;

    public SecurityController(IViewModelFactory<bool, SignInViewModel> viewModelFactory, 
                              IMembershipProvider membershipProvider, ILogger logger)
    {
        this.viewModelFactory = viewModelFactory;
        this.membershipProvider = membershipProvider;
        this.logger = logger;
    }

    public SecurityController()
    {
        this.viewModelFactory = new SignInViewModelFactory();
        this.membershipProvider = new MembershipProvider();
        this.logger = new NLogLogger();
    }

    [HttpPost]
    public ActionResult SignIn(SignInCommand command)
    {
        logger.Info("POST *** SecurityController: 
        Entering SignIn: Username={0}", command.Username);
        var user = membershipProvider.Find(command.Username, command.Password, true);
        if (user != null)
        {
            membershipProvider.SignIn(user, command.RememberMe);
            var redirectAction = Url.Action("Index", "Home");
            return Json(new { redirectAction });
        }

        var model = viewModelFactory.Create(true);
        model.SignInError = "Your credentials were not recognised. Please try again.";
        return Json(model);
    }
}

The great thing here is that it’s trivial to transition to using a DI framework later on. Once the framework is in place, you delete the parameterless constructors everywhere, job done. You’ll soon know if the framework isn’t wired up, because your app will start breaking. With that said, let’s take a look at a DI framework right now.

Enter Autofac (Think: Big White Horse, etc.)

Dependency Injection frameworks are great. They handle complex dependency chains with ease. They’re very good at managing and releasing memory when dependencies aren’t needed any more. They come with caveats, though. As the developer, you have to decide how long Autofac holds on to the memory for. That’s known as the scope. There are a few different scopes you can choose from. As a general rule, I would stick to using PerLifetimeScope. For an MVC application, Autofac creates a new lifetime scope for each HTTP request. That means that a new instance of each dependency will be created per HTTP request. When the request finishes, the dependencies will be disposed of. Here’s some useful reading on the topic:

Let’s see how to set up Autofac in an MVC and Web API project. First up, install the Nuget packages:

Install-Package Autofac.Mvc5
Install-Package Autofac.WebApi2

Now we need to register our dependencies with Autofac during application startup. This will either be in a Startup class or the Application_Start method in your Global.asax.cs. First of all, we’re going to add the dependencies to a couple of Autofac modules. It makes it easier to manage them going forward. Here they are:

public class WebModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterAssemblyTypes(typeof (WebModule).Assembly)
            .Where(t => t.IsClosedTypeOf(typeof (IViewModelFactory<,>)) || 
                   t.IsClosedTypeOf(typeof (IViewModelFactory<>)))
            .AsImplementedInterfaces().InstancePerLifetimeScope();
           
        builder.RegisterFilterProvider();
        builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>();
        builder.RegisterControllers(Assembly.GetExecutingAssembly()).InjectActionInvoker();

        builder.RegisterModule<CoreModule>();
    }
}

public class CoreModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<NLogLogger>().As<ILogger>().InstancePerLifetimeScope();
        builder.RegisterType<MembershipProvider>().As<IMembershipProvider>().InstancePerLifetimeScope();
        builder.RegisterType<UserHandler>().As<IUserHandler>().InstancePerLifetimeScope();
    }
}

The WebModule registers the CoreModule, which means you can chain modules together. We’re using InstancePerLifetimeScope everywhere. This means we’ll get a new instance of each dependency for each HTTP request. The ViewModelFactory code looks a bit weird. It’s a shorthand way to register generic types. I don’t have to add separate registrations for each combination of generic parameters. Autofac will hunt down the correct type for me based on the generic parameters.

Now that we have the modules in place, let’s add the code to register them, along with the MVC and Web API stuff. You can call ConfigureDependencies wherever you call RouteConfig.RegisterRoutes in your application. Add it straight after.

private static void ConfigureDependencies()
{
    var builder = RegisterDependencies();
    var container = builder.Build();

    ConfigureWebApi(container);
    ConfigureMvc(container);
}

private static ContainerBuilder RegisterDependencies()
{
    var builder = new ContainerBuilder();
    builder.RegisterModule<WebModule>();
    return builder;
}

private static void ConfigureWebApi(ILifetimeScope container)
{
    var webApiResolver = new AutofacWebApiDependencyResolver(container);
    GlobalConfiguration.Configuration.DependencyResolver = webApiResolver;

    var formatters = GlobalConfiguration.Configuration.Formatters;
    var jsonFormatter = formatters.JsonFormatter;
    var settings = jsonFormatter.SerializerSettings;
    settings.Formatting = Formatting.Indented;
    settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}

private static void ConfigureMvc(ILifetimeScope container)
{
    var mvcResolver = new AutofacDependencyResolver(container);
    DependencyResolver.SetResolver(mvcResolver);
}

The main things to note here are:

  • We’re setting the dependency resolver for Web API and MVC
  • We’re using the CamelCasePropertyNamesContractResolver, which affects AJAX calls to Web API. Whenever we call a Web API controller from JavaScript, the object that comes back will have JSON-friendly property names (e.g. firstName instead of FirstName)

That's all there is to it. If you want to introduce DI into your project, try the Poor Man's DI approach first:

  1. Wrap interfaces around any classes you "new up".
  2. Inject them in to a constructor.
  3. Create a parameterless constructor and initialise the dependencies.

Your code should become easier to maintain as a result. You can always add a DI container later on, when you're more comfortable with everything.

View the original article.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here