Dependency Injection in ASP.NET vNext
One of the big headlines of ASP.NET vNext is that dependency injection is built into the framework. It’s a pretty basic implementation of DI, but although it’s very basic I’m sure it will suffice for most applications. I’ll show how to set up and use the built in DI container below, but first…
What is Dependency Injection?
The best definition of DI I have found is from James Shore:
Dependency injection means giving an object its instance variables. Really. That’s it.
As James implies, it’s very simple, and essentially means a class gets the services it uses pushed to it rather than creating them itself. So for instance if you have an EF context you use to get data from a database, you would push the EF object to your class via dependency injection rather than instantiating the EF context in the class.
How do I use the vNext DI container?
This is definitely the easiest DI container to set up and configure out of all of the ones I have used. You should be able to get it up and running within 10 minutes on your own or in 9 minutes and 38 seconds if you follow this guide.
vNext Home
For this example we’ll use the ASP.NET vNext Home samples, specifically the HelloMvc
sample. For instructions on getting that up and running view my Getting Started with ASP.NET vNext post.
Dependency Injection in ASP.NET MVC
The dependency injection code can be found at https://github.com/aspnet/DependencyInjection. It is included in the MVC framework, however, which means that it’s already included in our Home repository which in turn means you don’t have to do anything!
Class
First things first – we need a thing to inject. Let’s create a TestContext
class to inject into our controllers that has a single method that returns the current date and time as a string. (And an interface for it, obviously!)
using System;
namespace HelloMvc.Test
{
public interface ITestContext
{
string GetDate();
}
}
using System;
namespace HelloMvc.Test
{
public class TestContext : ITestContext
{
public string GetDate()
{
return DateTime.Now.ToString();
}
}
}
Add Scoped
Now… our future controllers are going to ask for ITestContext
‘s and we need to tell the controller builder what concrete type to give it. This is where AddScoped<TService, TImplementation>
comes in. The AddScoped
method has generic type parameters for the interface type (what is asked for) and the implementation type (the concrete type passed in). It is an extension method to the IServiceCollection
class and you specify these in the Configure
method on app startup.
public void Configure(IBuilder app)
{
app.UseErrorPage();
app.UseServices(services =>
{
services.AddMvc();
services.AddScoped<ITestContext, TestContext>();
});
app.UseMvc();
app.UseWelcomePage();
}
Constructor Injection
Now, let’s update the HomeController
to ask for an ITestContext
. When a request comes in that the HomeController will handle, the controller builder will see it wants an ITestContext and will give it a concrete TestContext. I also updated the User
method to use the new context to set the user’s Name to the current date and time.
using Microsoft.AspNet.Mvc;
using MvcSample.Web.Models;
using HelloMvc.Test;
namespace MvcSample.Web
{
public class HomeController : Controller
{
private ITestContext _context;
public HomeController(ITestContext context)
{
_context = context;
}
public IActionResult Index()
{
return View(User());
}
public User User()
{
User user = new User()
{
Name = _context.GetDate(),
Address = "123 Real St."
};
return user;
}
public IActionResult Thing()
{
return View();
}
}
}
Now, if you run the app (run k web
from the command line, if you forgot) and you should see Hello 6/2/2014 8:04:05 PM!
(save for your current date and time, obviously).
And there you have it! A simple explanation of the new dependency injection service in ASP.NET vNext. Next time, we’ll look into using Ninject or StructureMap or some other IoC container with a vNext app.
UPDATE: New post is up that goes over setting up Castle Windsor.