dependency-injection

Injecting Services into MVC Views With ASP.NET Core

I've been exploring ASP.NET Core 1.0 for a little while now, and every step I take reinforces my opinion that Core is going to be a huge step forward for ASP.NET developers. However, in my eagerness to share all the stuff I'm learning, occasionally I forget to include something in one of my posts that really should have been there.

A young girl gives the Image found on Flickr and used under license

So I wrote a post about dependency injection in ASP.NET Core, but I totally missed one of the cooler features that Core added: you can now inject services into MVC views.

Yes, seriously. Here's how it works. Let's say that we have the following User class and the corresponding UserRepository interface and class:

public class User  
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; set; }
}

public interface IUserRepository  
{
    List<User> GetAll();
}

public class UserRepository : IUserRepository  
{
    public List<User> GetAll()
    {
        return new List<User>()
        {
            new User()
            {
                FirstName = "Jyn",
                LastName = "Erso",
                DateOfBirth = new DateTime(1983, 10, 17)
            },
            new User()
            {
                FirstName = "Cassion",
                LastName = "Andor",
                DateOfBirth = new DateTime(1979, 12, 29)
            },
            new User()
            {
                FirstName = "Bodhi",
                LastName = "Rook",
                DateOfBirth = new DateTime(1982, 12, 1)
            }
        };
    }
}

With such a setup, we're ready to use ASP.NET Core's native dependency injection container. Remember that in order to use said container we must register services in the Startup.cs file. Such a registration looks like this:

public void ConfigureServices(IServiceCollection services)  
{
    // Add framework services.
    services.AddMvc();

    services.AddTransient<IUserRepository, UserRepository>();
}

The next step is to create the (admittedly very simple) implementation of our Controller, which is as follows:

[Route("users")]
public class UsersController : Controller  
{
    [HttpGet]
    [Route("all")]
    [Route("~/")]
    public IActionResult GetAll()
    {
        return View();
    }
}

Finally, we can inject the service into a .cshtml view using the @inject keyword, which is new to ASP.NET Core 1.0. Here's the view for displaying these users:

@inject ViewInjectionCoreDemo.Repositories.IUserRepository userRepo

<h2>All Users</h2>

<table>  
    <thead>
        <tr>
            <th>
                First Name
            </th>
            <th>
                Last Name
            </th>
            <th>
                Date of Birth
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var user in userRepo.GetAll())
        {
            <tr>
                <td>
                    @user.FirstName
                </td>
                <td>
                    @user.LastName
                </td>
                <td>
                    @user.DateOfBirth
                </td>
            </tr>
        }
    </tbody>
</table>  

Running our sample app displays the following page:

That's really all there is to it! ASP.NET Core's Dependency Injection framework continues to impress me, and I'm looking forward to getting to use it all the time.

If you want to take a look at the repository for this demo, it's over on GitHub.

Happy Coding!

Getting Started with Dependency Injection in ASP.NET Core

I've lately been feeling my way around getting an actual, production-ready ASP.NET Core app developed, and one of the features I've really been digging (one of many) is native support for Dependency Injection (DI). DI is huge in modern web apps, so making it the default for ASP.NET Core applications is, IMO, a big step forward for this framework.

But, at the moment, the documentation page for dependency injection in ASP.NET Core has an example that just didn't click with me, and I believe that's because they didn't have any code examples to provide. In this post, I will provide two examples: one of my own design, and one which recreates an example provided in the official documentation; both of these sample projects are now over on GitHub. Let's learn how to use Dependency Injection in ASP.NET Core!

What Is Dependency Injection?

First, a few basics. The idea of Dependency Injection is that, when a class is created, it should have its dependent classes injected into it rather than created by it. This provides a situation in which we have loose coupling and high cohesion, an ideal which many software programs strive toward.

The ASP.NET Core documents explains it like this:

"[When using DI, ]Rather than directly instantiating collaborators, or using static references, the objects a class needs in order to perform its actions are provided to the class in some fashion. Most often, classes will declare their dependencies via their constructor, allowing them to follow the Explicit Dependencies Principle. This approach is known as 'constructor injection'."

Constructor injection is by far the most common approach to implementing DI, though not the only one. ASP.NET Core uses constructor injection in its solution, so (obviously) we will also do so.

Finally, note that there are many DI frameworks out there in addition to the native ASP.NET Core one, including StructureMap, Autofac, Ninject, SimpleInjector, and several others. StructureMap is my personal favorite, but all of these frameworks do roughly the same thing. Try a few to figure out which fits your style; in this demo I will use the native ASP.NET Core DI container.

A Basic DI Example

To demonstrate how Dependency Injection works in an ASP.NET Core app, let's set up a basic MVC app as a demo.

Pretend we need to model a list of users for our application. The class which represents these users might look like this:

public class User  
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string Username { get; set; }
}

We will also need an interface and repository for retrieving the users. The interface and class will look like this:

public interface IUserRepository  
{
    List<User> GetAll();
}

public class UserRepository : IUserRepository  
{
    public List<User> GetAll()
    {
        return new List<User>()
        {
            new User()
            {
                FirstName = "Ash",
                LastName = "Ketchum",
                DateOfBirth = new DateTime(1997, 12, 30),
                Username = "ichooseyou"
            },
            new User()
            {
                FirstName = "Brock",
                LastName = "Harrison",
                DateOfBirth = new DateTime(1992, 3,31),
                Username = "rockrulez"
            },
            new User()
            {
                FirstName = "Misty",
                LastName = "",
                DateOfBirth = new DateTime(1999, 5,4),
                Username = "ihearttogepi"
            }
        };
    }
}

The reason we need an interface here is because our MVC controllers will reference the interface, not the class. Speaking of the controller, let's define one now:

public class HomeController : Controller  
{
    private readonly IUserRepository _userRepo;

    public HomeController(IUserRepository userRepo)
    {
        _userRepo = userRepo;
    }

    [HttpGet]
    public IActionResult Index()
    {
        return View(_userRepo.GetAll());
    }
}

Notice the setup here. We have a private readonly instance of our interface IUserRepository, and the constructor takes an instance of IUserRepository and sets our private instance to the passed-in instance. This is constructor injection at its simplest.

But we're not done yet. As I've discussed previously on this blog, ASP.NET Core projects have a Startup.cs file, which configures the environment in which our app will run. The Startup.cs file also places services into ASP.NET Core's Services layer, which is what enables dependency injection.

Here's how we must modify our Startup.cs file to inject IUserRepository into our controller:

public void ConfigureServices(IServiceCollection services)  
{
    // Add framework services.
    services.AddMvc();

    //Basic demo
    services.AddTransient<IUserRepository, UserRepository>();
}

We'll discuss what AddTransient<>() means in the next section. For now, let's run the app.

Here's what our page looks like when we get there:

Note that once we added the IUserRepository to the Services layer, ASP.NET Core automatically injected it into our HomeController class. That's pretty neat!

But, what exactly does AddTransient<>() do in the Startup file? To discuss that, we must first discuss what ASP.NET Core uses as lifetimes for its services.

Dependency Injection Lifetimes

In ASP.NET Core's DI implementation, we see the concept of "lifetimes". A lifetime specifies when a DI-injected object gets created or recreated. There are three possibilities:

  • Transient: Created each time they are requested.
  • Scoped: Created once per request.
  • Singleton: Created the first time they are requested. Each subsequent request uses the instance that was created the first time.

The ASP.NET Core official documentation provides a walkthrough of sorts for how these lifetimes behave, but I'm not satisfied with that example as it skips over a few sections of code that I think are rather important and doesn't provide a working example. I've reproduced it here, with a full working codebase which, like the earlier example, is over on GitHub.

To demonstrate how these lifetimes work, let's define a few interfaces. We'll need an interface IOperation which represents an operation being done in each of these lifetimes. Said operation will do one thing: it will return either Guid.NewGuid() or the passed-in Guid value from its one method. We'll also define four additional interfaces, each of which represents that operation during a specific lifetime:

public interface IOperation  
{
    Guid GetCurrentID();
}

public interface IOperationTransient : IOperation { }

public interface IOperationScoped : IOperation { }

public interface IOperationSingleton : IOperation { }

public interface IOperationSingletonInstance : IOperation { }  

IOperationSingletonInstance is a special form of this operation which will always return a blank Guid.

Now we can define the Operation class itself, which implements the four lifetime interfaces and defines the GetCurrentID() method.

public class Operation : IOperationTransient, IOperationScoped, IOperationSingleton, IOperationSingletonInstance  
{
    public Guid Guid { get; set; }

    public Operation()
    {
        Guid = Guid.NewGuid();
    }

    public Operation(Guid guid)
    {
        Guid = guid;
    }

    public Guid GetCurrentID()
    {
        return Guid;
    }
}

Our Operation class will either return Guid.NewGuid() or used the Guid passed in to the constructor (this scenario is for the IOperationSingletonInstance interface demo).

However, to fully show how Transient operations work, we also need to define another class which represents a separate set of instances of these interfaces (separate from the ones being injected into our controller). We'll call this class OperationServices and it looks like this:

public class OperationService  
{
    public IOperationTransient TransientOperation { get; }
    public IOperationScoped ScopedOperation { get; }
    public IOperationSingleton SingletonOperation { get; }
    public IOperationSingletonInstance SingletonInstanceOperation { get; }

    public OperationService(IOperationTransient transientOperation,
        IOperationScoped scopedOperation,
        IOperationSingleton singletonOperation,
        IOperationSingletonInstance instanceOperation)
    {
        TransientOperation = transientOperation;
        ScopedOperation = scopedOperation;
        SingletonOperation = singletonOperation;
        SingletonInstanceOperation = instanceOperation;
    }
}

Now we need to register the four lifetime interfaces and our OperationServices class into our Dependency Injection container. We do so in the Startup class's ConfigureServices() method, just like we registered the IUserRepository class earlier.

public void ConfigureServices(IServiceCollection services)  
{
    // Add framework services.
    services.AddMvc();

    //Basic demo
    services.AddTransient<IUserRepository, UserRepository>();

    //Lifetimes demo
    services.AddTransient<IOperationTransient, Operation>();
    services.AddScoped<IOperationScoped, Operation>();
    services.AddSingleton<IOperationSingleton, Operation>();
    services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));
    services.AddTransient<OperationService, OperationService>();
}

With all our dependencies registered, we can now create an OperationsController which will demo how these lifetimes work.

public class OperationsController : Controller  
{
    private readonly OperationService _operationService;
    private readonly IOperationTransient _transientOperation;
    private readonly IOperationScoped _scopedOperation;
    private readonly IOperationSingleton _singletonOperation;
    private readonly IOperationSingletonInstance _singletonInstanceOperation;

    public OperationsController(OperationService operationService,
        IOperationTransient transientOperation,
        IOperationScoped scopedOperation,
        IOperationSingleton singletonOperation,
        IOperationSingletonInstance singletonInstanceOperation)
    {
        _operationService = operationService;
        _transientOperation = transientOperation;
        _scopedOperation = scopedOperation;
        _singletonOperation = singletonOperation;
        _singletonInstanceOperation = singletonInstanceOperation;
    }

    public IActionResult Index()
    {
        // viewbag contains controller-requested services
        ViewBag.Transient = _transientOperation;
        ViewBag.Scoped = _scopedOperation;
        ViewBag.Singleton = _singletonOperation;
        ViewBag.SingletonInstance = _singletonInstanceOperation;

        // operation service has its own requested services
        ViewBag.Service = _operationService;
        return View();
    }
}

For posterity, I will also include the .cshtml file which displays the results of that Index() action:

@{
    ViewData["Title"] = "ASP.NET Core Dependency Injection Demo";
}

<h2>Lifetimes</h2>

<span>Controller Operations</span>  
<ul>  
    <li><strong>Transient:</strong> @ViewBag.Transient.GetCurrentID()</li>
    <li><strong>Scoped:</strong> @ViewBag.Scoped.GetCurrentID()</li>
    <li><strong>Singleton:</strong> @ViewBag.Singleton.GetCurrentID()</li>
    <li><strong>Singleton Instance:</strong> @ViewBag.SingletonInstance.GetCurrentID()</li>
</ul>  
<span>OperationService Operations</span>  
<ul>  
    <li><strong>Transient:</strong> @ViewBag.Service.TransientOperation.GetCurrentID()</li>
    <li><strong>Scoped:</strong> @ViewBag.Service.ScopedOperation.GetCurrentID()</li>
    <li><strong>Singleton:</strong> @ViewBag.Service.SingletonOperation.GetCurrentID()</li>
    <li><strong>Singleton Instance:</strong> @ViewBag.Service.SingletonInstanceOperation.GetCurrentID()</li>
</ul>  

Testing the Lifetimes

With all of our code in place, we are now ready to test. Let's look at two screenshots of that demo page. The first screenshot is when we first load the page.

The second screenshot is of the same page after doing a refresh:

We need to notice a few things about the differences in these screenshots:

  • Each time it shows up, the Transient Guid is different.
  • The Scoped Guids are the same for both calls in a single screenshot, but not in each screenshot.
  • The Singleton Guids are the same all four times they are called.
  • The Singleton Instance Guids (as expected) are always 0s.

I personally find that the differences are easier to spot if I see them in real-time, so I made this gif:

A short demo showing the differences between Transient, Scoped, and Singleton services in ASP.NET Core

Summary

One of the best new features coming from ASP.NET Core is the inclusion of its own lightweight Dependency Injection container. In this post, we've seen how to inject a simple service into a controller, and we've seen the three DI lifetimes (Transient, Scoped, Singleton) and how they behave differently from one another.

As always, please feel free to check out the code base for this post over on GitHub and let me know if you see any improvements I could make.

Happy Coding!

Setting Up Dependency Injection in Web API with StructureMap

Up until recently I hadn't really used any Dependency Injection (DI) frameworks in my ASP.NET projects, largely due to them being rather intimidating to set up the first time. I mean, I barely grasp the concept of DI, so the thought of trying to implement it on my own is worrisome.

Recently, though, my group had a requirement that forced us to consider using a DI framework (which I wrote about in Custom Validation in ASP.NET Web API using FluentValidation) for an ASP.NET Web API project we're in the process of building. We needed a way to pass dependencies to multiple consumers, particularly Web API controller classes and back-end repositories. Further, we needed the solution to be testable, and to be relatively easy to change when necessary.

I started researching different DI setups, and eventually stumbled across one called StructureMap, which after just an hour of exploring, seemed to provide everything our solution needed. The worry I had foreseen was reduced to mere trepidation, and just a little more research showed the kind of power that Dependency Injection really holds.

Of course, if it helps us, it will help someone else out there; hence this post. Let's explore getting started with Dependency Injection in ASP.NET Web API, using StructureMap!

Creating the Project

Let's start at the very beginning (a very good place to start).

Let's create a new Web API project in Visual Studio. I called mine StructureMapWebAPIDemo.

A screenshot of the Visual Studio New Project window.

A screenshot of the Visual Studio New Web Project window, with Web API and No Authentication selected

We'll end up with a project that looks a lot like this:

A screenshot of the initial layout of the Web API project

Setting Up the Library and Repositories

Before we do anything else, let's set up our library project. Add a new Class Library to the solution (I called mine StructureMapWebAPIDemo.Lib) with folders called Interfaces, Repositories, and DataModel. The structure will look like this:

A screenshot of the StructureMapWebAPIDemo.Lib project layout, including folders for DataModel, Repositories, and Interfaces

We'll need a data model class to interface with, so let's create a class called Movie.

public class Movie  
{
    public int ID { get; set; }
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
    public int RunningTimeMinutes { get; set; }
    public string Director { get; set; }
}

We'll also need a Repository and an Interface to retrieve the movies. Here's those classes.

public interface IMovieRepository  
{
    List<Movie> GetAllMovies();
    Movie GetByID(int id);
}

public class MovieRepository : IMovieRepository  
{
    public List<Movie> GetAllMovies()
    {
        return new List<Movie>()
        {
            new Movie()
            {
                ID = 1,
                Title = "The Incredibles",
                ReleaseDate = new DateTime(2004, 11, 5),
                RunningTimeMinutes = 116,
                Director = "Brad Bird"
            },
            new Movie()
            {
                ID = 2,
                Title = "Wreck-It Ralph",
                ReleaseDate = new DateTime(2012, 11, 2),
                RunningTimeMinutes = 120,
                Director = "Rich Moore"
            },
            new Movie()
            {
                ID = 3,
                Title = "Inside Out",
                ReleaseDate = new DateTime(2015, 6, 19),
                RunningTimeMinutes = 102,
                Director = "Pete Doctor & Ronnie Del Carmen"
            }
        };
    }

    public Movie GetByID(int id)
    {
        var allMovies = GetAllMovies();
        if (allMovies.Where(x => x.ID == id).Any())
        {
            return allMovies.First(x => x.ID == id);
        }
        else return null;
    }
}

All the repository does is return either a collection of movies, or an individual movie (or null if given a movie ID that doesn't exist).

Now that we've got our library set up, we can integrate StructureMap.

Adding StructureMap

In the Web API project, let's add a NuGet package called StructureMap.WebApi2. On doing so, we'll see that the structure of the project has changed:

The new files are what allow StructureMap to operate in our Web API project, and if you'd like more information about them, check out the GitHub documentation. Luckily for us, we don't strictly need to know what these files do in order to use them (though understanding what you are building is always a good idea).

Modifying the Controllers

We have one controller in this project at the moment, HomeController. Let's remove this controller and replace it with our own MovieController and two actions which use the MovieRepository from earlier:

[RoutePrefix("movies")]
public class MovieController : ApiController  
{
    [HttpGet]
    [Route("all")]
    public IHttpActionResult All()
    {
        MovieRepository movieRepo = new MovieRepository();
        var allMovies = movieRepo.GetAllMovies();
        return Ok(allMovies);
    }

    [HttpGet]
    [Route("{id}")]
    public IHttpActionResult GetByID(int id)
    {
        MovieRepository movieRepo = new MovieRepository();
        var movie = movieRepo.GetByID(id);
        if(movie == null)
        {
            return NotFound();
        }
        return Ok(movie);
    }
}

On first glance, this all seems fine and dandy. After all, the All() and GetByID() are pretty descriptive insofar as what they do. The issue arises when the implementation of the MovieRepository needs to change.

Let's say (for the sake of argument) that we need to be flexible about what implementation we want for the MovieRepository. Maybe we need to support different data storage systems, maybe we need the possibility of changing the actual code for different scenarios, what have you. The problem we have right now is that new is glue; that is, creating a dependency using the new keyword binds the dependency to the current implementation, whatever that happens to be. If the implementation of the MovieRepository changes, it's likely the code in the MovieController will also need to change.

But what if it didn't have to?

That's the core philosophy behind using a DI container: separate the implementation from the interface. In this way, if the implementation changes, the classes which need that implementation don't actually care, because the interface to the implementation didn't (necessarily) change.

Here's what we need: we need the MovieController to be aware of an interface to the implementation, not the implementation itself. We can do this by creating a private variable in the MovieController class for the repository's interface and assigning the implementation of that interface in the constructor:

[RoutePrefix("movies")]
public class MovieController : ApiController  
{
    private readonly IMovieRepository _movieRepo;

    public MovieController(IMovieRepository movieRepo)
    {
        _movieRepo = movieRepo;
    }

    [HttpGet]
    [Route("all")]
    public IHttpActionResult All()
    {
        var allMovies = _movieRepo.GetAllMovies();
        return Ok(allMovies);
    }

    [HttpGet]
    [Route("{id}")]
    public IHttpActionResult GetByID(int id)
    {
        var movie = _movieRepo.GetByID(id);
        if(movie == null)
        {
            return NotFound();
        }
        return Ok(movie);
    }
}

Now we've got our controller set up perfectly. All we need now are two more steps.

In the DependencyResolution folder's DefaultRegistry.cs file, we need to register the MovieRepository with the DI container:

public class DefaultRegistry : Registry {  
    public DefaultRegistry() {
        Scan(
            scan => {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
            });
        For<IMovieRepository>().Use<MovieRepository>();
    }
}

Finally, in the App_Start/WebApiConfig.cs file, we need to start up the DI container:

public static class WebApiConfig  
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        StructuremapWebApi.Start();

        ....
    }
}

This is how we tell StructureMap to inject an instance of MovieRepository into MovieController's constructor for the interface IMovieRepository.

Testing the Controllers

One of the primary benefits of switching to a DI container such as StructureMap is the improved ability to test our code. Unit testing the MovieRepository doesn't change, but unit testing the MovieController does, due to the constructor injection we're performing on it.

Let's set up a stub test class for testing the MovieController:

[TestClass]
public class MoviesControllerTests  
{
    [TestMethod]
    public void Test_GetByID_ValidID()
    {
        //Arrange

        //Act

        //Assert
    }

    [TestMethod]
    public void Test_GetByID_InvalidID()
    {
        //Arrange

        //Act

        //Assert
    }
}

We're going to test two scenarios: when we call the controller's GetByID action with a valid ID, and with an invalid ID.

Valid Movie ID test

Let's write the valid ID test first. The general order of operations for any test is arrange, act, assert.

Arrange

First, we need to arrange the components being tested, as well as their dependencies. Remember that the point of this test is to test the controller, not the repository, and so we'll be mocking the MovieRepository using Moq:

//Arrange
var movieID = 2;  
var mockMovieRepo = new Mock<IMovieRepository>();  
mockMovieRepo.Setup(x => x.GetByID(movieID)).Returns(new Movie() { ID = 2 });  
var controller = new MoviesController(mockMovieRepo.Object);  

Act

Now, we need to perform the action we are testing. Remember that since we are testing a controller, we will get back an IHttpActionResult response, and need to convert that to an appropriate response class (in our case, OkNegotiatedContentResult). Here's the next part of the method:

//Act
IHttpActionResult response = controller.GetByID(movieID);  
var contentResult = response as OkNegotiatedContentResult<Movie>;  

Assert

Finally, we need to assert that three things are true:

  1. The response itself is not null.
  2. The content of the response is not null.
  3. The movie ID we submitted to the controller is the same as the ID of the movie returned.

That code looks like this:

//Assert
Assert.IsNotNull(contentResult);  
Assert.IsNotNull(contentResult.Content);  
Assert.AreEqual(movieID, contentResult.Content.ID);  

The complete test method looks like this:

[TestMethod]
public void Test_GetByID_ValidID()  
{
    //Arrange
    var mockMovieRepo = new Mock<IMovieRepository>();
    var movieID = 2;
    mockMovieRepo.Setup(x => x.GetByID(movieID)).Returns(new Movie() { ID = 2 });
    var controller = new MoviesController(mockMovieRepo.Object);

    //Act
    IHttpActionResult response = controller.GetByID(movieID);
    var contentResult = response as OkNegotiatedContentResult<Movie>;

    //Assert
    Assert.IsNotNull(contentResult);
    Assert.IsNotNull(contentResult.Content);
    Assert.AreEqual(movieID, contentResult.Content.ID);
}

Invalid Movie ID Test

Now we can complete the other test, where we're testing for the result for an invalid ID. In this scenario, the response should be 404 Not Found.

[TestMethod]
public void Test_GetByID_InvalidID()  
{
    //Arrange
    var mockMovieRepo = new Mock<IMovieRepository>();
    var movieID = 6; //This movie does not exist
    mockMovieRepo.Setup(x => x.GetByID(movieID)).Returns((Movie)null);
    var controller = new MoviesController(mockMovieRepo.Object);

    //Act
    IHttpActionResult response = controller.GetByID(movieID);
    var contentResult = response as NotFoundResult;

    //Assert
    Assert.IsNotNull(contentResult);
}

Summary

Dependency Injection's primary purpose is to separate the implementation from the interface, and allow the system to supply the implementation at a given time. StructureMap (and it's Web API implementation) provide most of the groundwork to do just that, and all we programmers have to do is:

  • Register the dependencies
  • Set up the controllers to use injection
  • Test

And then we can sick back and sip our margaritas. Or get back to work. Whichever.

I've got a sample project for this post over on GitHub, so go check it out!

Happy Coding!