ASP.Net Core has a built-in dependency framework. This means you don't need to write your own plumbing code to achieve Dependency Injection. ASP.Net Core helps enforces the Dependency Injection Principle out of the box.
What is a dependency?
Dependency is established between classes when one class needs another class to fulfil its functionality. Below are two classes class A and class B. Class A needs class B to accomplish the addition functionality. So class A has a dependency on class B or class A is dependent on class B.
class A{
public int addition(int x, int y)
{
B objB = new B();
return objB(x,y);
}
}
While this is a perfectly viable situation to do, it makes class A very tightly coupled with class B. To further elaborate on this, imagine you discovered a faster algorithm in class C. You would now have to rewrite class A, remove the dependency on B and use C instead. While this doesn't seem difficult to do in their example it may not be the same if this dependency has been used in several places throughout your code.
Dependency injection
Is there a better way to manage a dependency? Yes there is and its called Dependency Injection. Instead of letting class A manage the creation of class B, we delegate this responsibility to the class calling class A and then injecting that object into class A when required.
class A{
private B _objB;
public A(B objB)
{
_objB = objB;
}
public int addition(int x, int y)
{
return _objB(x,y);
}
}
class Program{
public static void main(string args[])
{
B objB = new B();
A objA = new A(objB);
Console.WriteLine(obja.addition(4,5).ToString());
}
}
Dependency injection in ASP.Core
Step1: Create an interface for our service called IMyService.
interface IMyService{
public void GetMyUsers();
}
Step2: Create a service called MyService that implements interface IMyService.
public class MyService: IMyService{
public void GetMyUsers(){
//****Do something here *****
}
}
public class Startup{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IMyService, MyService>();
}
}
Step4: In your controller class you can inject MyService in the constructor and use it like below.
public class MyController : ControllerBase{
private IMyService _myService;
public MyController(MyService _myService)
{
_myService = myService;
}
[HttpGet]
[Route("/api/user")]
public IActionResult Get()
{
_myService.GetMyUsers();
}
}
Using Service Extensions
You can call write your own service extensions services.Add{SERVICE_NAME} by extending the ServicesConfiguration class like below.
public static class ServicesConfiguration{
public static void AddMyService(this IServiceCollection services)
{
services.AddScoped<IMyService, MyService>();
}
}
You can then use it in the Startup class like below.
public class Startup{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IMyService, MyService>();
}
}
Service lifetimes
Transient
This is probably the default choice, its best suited for lightweight and stateless services. You can use this method in applications that don't implement a request-response pattern.
Scoped
This is best suited for web applications as it is created once per client request.
Singleton
This is created once for the life of the application. There is only one instance of this service.