Sample Example using Asp.net core
Recorded Video Link: https://www.youtube.com/watch?v=oVj1IHw8GLU
OverviewOfDI: https://github.com/sandeepmvn/DependencyInjectionRepository/blob/master/OverviewOfDI.txt
ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies.
Through IoC container, we can achieve
In Asp.net core, IoC Container has built-in interfaces.
The following DI Lifecycle will be
There are basically two types of services in ASP.NET Core:
Framework Services: Services which are a part of ASP.NET Core framework such as IApplicationBuilder, IHostingEnvironment, ILoggerFactory etc.
Application Services: The services (custom types or classes) which you as a programmer create for your application.
Asp.Net Core MVC controller request dependencies explicitly via constructors 1. Constructor Injection 2. Method Injection (Action level) 3. Propery Injection (not supported) 4. View Injection
Constructor Injection: - Services are added as a constructor parameter and runtime resolve the service from the service container (IServiceCollection-- DiContainer). Servicesa are typically defined using non-concrete class (interfaces)
Method Injection : - Using [FromService] attribute enables injecting service directly into an action method without using controller injection
Property Injection Currently(Asp.net core) bulit-in IOC container doesn't support property injection.For this you might go for third-party built-in service containers (IOC).
View Injection Using [Inject] directive enables injecting service directly into view page without using controller or method injection
The built-in IoC container support three kinds of lifetime:
In the sample example, "IMyDependency" service interface defines "WriteMessage" method
public interface IMyDependency
{
void WriteMessage(string message);
}
This interface is implemented by a concrete type, MyDependency:
public class MyDependency : IMyDependency
{
public void WriteMessage(string message)
{
Console.WriteLine($"MyDependency.WriteMessage Message: {message}");
}
}
Now, Registers the "IMyDependency" service with the concrete type "MyDependency" (in startup.cs)
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.Add(new ServiceDescriptor(typeof(IMyDependency), new MyDependency()));
}
}
Here Add() method of "IServiceCollection" instance is used to register a service with an IoC container. The "ServiceDescriptor" is used to specify the type of service and concrete implementation. This will register our service in container with default as "Singleton"
Now, let's inject services with different life times
Singleton (Use case : when we need to create state service) :
services.Add(new ServiceDescriptor(typeof(IMyDependency), new MyDependency(),ServiceLifetime.Singleton));
Transient (Use case : when we need to create stateless service):
services.Add(new ServiceDescriptor(typeof(IMyDependency), new MyDependency(),ServiceLifetime.Transient));
Scoped (Use case : Database service):
services.Add(new ServiceDescriptor(typeof(IMyDependency), new MyDependency(),ServiceLifetime.Scoped));
We can also inject the services using bulit-in extension methods
Singleton
services.AddSingleton
Transient
services.AddTransisent
Scoped
services.AddScoped
public class HomeController : Controller { private readonly IMyDependency _service;
public HomeController(IMyDependency service)
{
_service = service;
}
public IActionResult Index()
{
_service.WriteMessage("Constructor level injection")
return View();
}
}
public class HomeController : Controller
{
//Fromservice attribute
public IActionResult Index([FromService]IMyDependency service)
{
service.WriteMessage("Action level injection")
return View();
}
}
public class HomeController : Controller {
public IActionResult Index()
{
return View();
}
}
In Index.cshtml
@{ ViewData["Title"] = "Home Page"; }
//using Inject directive
@inject IMyDependency service
//code block
@{
service.WriteMessage("View level Injection");
}
public class HomeController : Controller {
public IActionResult Index()
{
var services = this.HttpContext.RequestServices;
var dependencyservice = (IMyDependency)services.GetService(typeof(IMyDependency));
dependencyservice.WriteMessage("without injection, accessing dependent services");
return View();
}
}