Dependency injection in ASP.NET Core

ASP.NET 5 has dependcy injection available at framework level and ASP.NET 5 makes heavy use of it. Most of things surrounding controllers, views and other MVC components are implemented as services that web applications consume. This post is quick overview of dependency injection in ASP.NET 5 with some examples.

Registering services

Services are registered when application starts. It happens in Startup class. There is method called ConfigureServices() and in the end of this method I usually define service mappings.

public virtual void ConfigureServices(IServiceCollection services)
{
    // configure services 
    var settings = new Settings(); 

    // initialize custom settings 
    services.AddInstance(settings);
    services.AddScoped<IFileClient, AzureFileClient>();
    services.AddScoped<IMapperSession, MapperSession>();
    services.AddScoped<IProductService, ProductService>();
}

Available scopes for services are:

  • SIngleton – always return same instance,
  • Transient – return new instance every time.
  • Scoped – return same instance in current scope (it’s like singleton in current scope – think about requst scope by example).
  • Instance – specific instance is returned every time and it’s up to you how it is actually ceated

Services registered during application start-up are available to all classes invoked through dependency injection.

Although we can inject services to whatever classes you need there are some things made very convenient for us. Let’s see now how injection works with controllers and views. Yes, views too.

Injecting services to controller

We don’t need custom controller factories anymore if we don’t use some other dependency injection container. Also we don’t have to dig around in system variables and classes to find settings we need. We can do it all through dependency injection. Here is the example how to provide environment information and some custom services to controller.

public class HomeController : Controller
{
    private readonly IApplicationEnvironment _appEnvironment;
    private readonly ShopContext _shopContext;
    private readonly IProductService _productService;
 
    public HomeController(ShopContext shopContext, 
                          IProductService productService, 
                          IApplicationEnvironment appEnvironment)
    {
        _appEnvironment = appEnvironment;
        _shopContext = shopContext;
        _productService = productService;
    }
 
    public IActionResult Index()
    {
        return View();
    }
 
    // ... more methods follow ...
}

The code here uses controller injection – the only injecton mode supported by ASP.NET right now. We don’t have to do anything special for dependency injection to happen. We just make sure we register our custom services at application startup.

Injecting services to views

It’s also possible now to inject services to views. There’s new syntax for this.

@model ProductCategoryMenuModel
@inject
 ShopContext ShopContext

<h1>@ShopContext.PageTitle</h1>

<
ul>
   
<!-- write out categories here -->
</ul
>

@inject tells to view engine that we want instance of ShopContext to be injected to view and we name it as ShopContext. Perhaps it’s not a good practice to name variable as type in view but still it communicates the purpose of variable well.

Conclusion

Framework level dependency injection in ASP.NET 5 is very transparent and configuration is simple. First register type mappings in application start-up and then we use constructor injection to get instances to our classes. This way we can use classes by interfaces and we don’t have to create instances in our own code. On MVC side we can use dependency injection for controller, views and view components.

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    8 thoughts on “Dependency injection in ASP.NET Core

    • August 4, 2015 at 5:33 am
      Permalink

      Have you got an example of why it’d be a good idea to inject a service for use directly in a view?

    • August 4, 2015 at 1:15 pm
      Permalink

      Yes, sure. Consider layout page where you want to show some data on sidebar that is not part of content area filled by controller action. I more see that object injected to view is some custom request context that carries data to layout page and view components so we don’t have to use property bags and view bags.

    • Pingback:Szumma #002 – 2015 32. hét | d/fuel

    • August 10, 2015 at 8:40 pm
      Permalink

      It seems like injecting the service into the view is going against separation of concerns? To keep your view from coupling tightly to the service would it be better to only pass models to the view? Injecting the service into the controller and mapping the return from the service to a model would offer nice clean layers of abstraction.

    • August 11, 2015 at 1:50 pm
      Permalink

      Casey,

      Totally agreed. Just because you *can*, doesn’t mean you *should*. In this particular case, I think it was a mistake for the ASP.NET team to implement the feature but perhaps someone will find a legitimate case one day.

    • August 12, 2015 at 8:14 am
      Permalink

      Good case is custom request context where one may have properties specific to web site and request. It’s possible to inject this additional context to all parts of system where it is needed and it has therefore a little higher flight than ViewBag has. I will write some more posts to cover new stuff in ASP.NET 5 and practical example of view injection is one of these.

    • Pingback:ASP.NET Core 中的框架级依赖注入 | Codeba

    • Pingback:详解ASP.NET Core 中的框架级依赖注入 – 科网

    Leave a Reply

    Your email address will not be published. Required fields are marked *