Dependency injection in ASP.NET 5

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.


6 thoughts on “Dependency injection in ASP.NET 5

  • Pofox says:

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

  • Gunnar says:

    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.

  • […] Dependency injection in ASP.NET 5 – hasznos és rövid összefoglaló az ASP.NET 5 és a DI barátságáról. […]

  • 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.

  • Tommy Long says:

    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.

  • Gunnar says:

    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.

Leave a Reply

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