Dependency Injection in ASP.Net Core

ASP.NET Core has built in support for dependency injection, which we'll discuss in this article.

Dependency injection (DI) is a technique for achieving loose coupling between objects and their dependencies. Dependency injection is one of the Dependency Inversion Principle techniques, allowing for applications to be composed of loosely coupled modules

The built in DI Container

ASP.NET Core includes a simple built-in container (IServiceProvider) that supports constructor injection by default. Types registered in this container are refered as services. You configure the built-in container's services in the ConfigureServices method in your application's Startup class.

The mostly used dependency injection technique in ASP.NET Core is Constructor Injection. By simply adding a service type to your controller as a constructor parameter, ASP.NET Core will attempt to resolve that type using its built in service container(IServiceProvider). Services are typically defined using interfaces, but can be also registered as concrete classes.

Constructor injection requires that the constructor is public, and that only one applicable constructor exist.

Framework Provided Services

Additionally to some default services which are registered by default(depending of how the host was configured), additional services can be registered in the container using a number of extension methods like AddDbContext, AddIdentity, and AddMvc. This extensions are known as middleware, for example AddMvc will add all services required for Mvc

public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
...
}

Registering user defined services

You can register your own application services, by calling same methods on the IServiceCollection interface. The first generic type represents the type (typically an interface) that will be requested from the container. The second generic type represents the concrete type that will be instantiated by the container:

services.AddTransient<IEmailSender, ConcreteEmailSender>();

Lifetime of Services

In ASP.NET core we have 3 major dependency injection lifetimes :

Singleton which creates a single instance throughout the application. It creates the instance for the first time and reuses the same object in the all calls.
services.AddSingleton<IOperationSingleton, Operation>();

Scoped lifetime services are created once per request within the scope. It is equivalent to Singleton in the current scope. eg. in MVC it creates 1 instance per each http request but uses the same instance in the other calls within the same web request.
services.AddScoped<IOperationScoped, Operation>();

Transient lifetime services are created each time they are requested. This lifetime works best for lightweight, stateless services.
services.AddTransient<IOperationTransient, Operation>();

Dependency injection tehniques into controllers

Constructor Injection

Controllers should request their dependencies via their constructors. By having an Interface as a controller argument, ASP.NET will attempt to resolve that type using its built in service container.

In order to register a new service, we have to add it to the IServiceCollection in the Startup class:

public void ConfigureServices(IServiceCollection services)
{
// Add application services.
services.AddTransient<IDateTime, SystemDateTime>();
}

Having the Service registered, we can retrieve it by passing it to the controller contructor:

public class HomeController : Controller
{
private readonly IDateTime _dateTime;

public HomeController(IDateTime dateTime)
{
_dateTime = dateTime;
}

Action Injection

Sometimes you need a service for only one action within your controller. In this case, it makes sense to inject the service as a parameter to the action method. This is done by adding the attribute [FromServices]:

public IActionResult MyView([FromServices] IDateTime dateTime)
{
ViewData["Message"] = "Current time " + dateTime.Now;

return View();
}

Disposing of registered services

As with any dependency injection container, the container will call Dispose for IDisposable types it creates. Be aware that if you add an instance to the container yourself, it will not be disposed:

services.AddSingleton(new Service());


ASP.NETCore
ASP.NET Core dependency injection

23.07.2018

Acasa
pinte dan
About the Author

Dani Pinte

Dani is a software developer with over 10 years experience in developing Desktop and Web applications using Microsoft .NET Technologies. He is passionate about software, sports, travel and motorsport.



Razor Pages in ASP.NET Core