×

iFour Logo

Dependency Injection in Asp.Net Core

Kapil Panchal - October 27, 2020

Listening is fun too.

Straighten your back and cherish with coffee - PLAY !

  • play
  • pause
  • pause
Dependency Injection in Asp.Net Core

What is Dependency Injection?


Dependency Injection technique is used tocreate a maintainable code in .Net Core.The Dependency Injection provides extensive support in .Net Core, it depends onyou how to apply it. The class and their dependencies to achieve inversion of controlin dependency injection. A dependency is an object depends on another object. It is also called DI. The Dependency Injection provide loose coupling and promotes testability and maintenance. DI used to design pattern used implemented to IoC.

There are three types of class in Dependency Injection pattern:

1. Client Class:-> This is dependent class it depends on service class.

2. Service Class:-> That class provides service to the client class in the service class.

3. Injector Class:-> It injects to the service class object into the client class.

Overview of Dependency Injection


You can understand the Dependency Inversion Principle so it is helpful before initiating Dependency Injection, it gives us the guidelines for loosely-coupled classes.

  • Low level modules should depend on high-level modules and both are depending on abstractions.
  • The details should depend upon abstractions but abstractions should not depend upon details.

This is actually mechanism of you can use to make higher-level modules that depends on abstraction.You can create a class of MyDependency and create a Message method in Asp.Net Core.

Example:

publicclassMyDependency
{
  publicvoidMessage (string message)
    {
      Console.WriteLine($"My Dependency.Message called. Message: {message} ");
    }
}
                 

In the MyDependency.cs file, you can add another class, IndexModel and derived to PageModel and create a variable name of MyDependency. Create a new method of OnGet in this method you will pass theMydependency method.

Example:

publicclassIndexModel: PageModel
    {
  privatereadonlyMyDependency _dependency = newMyDependency ();

publicvoidOnGet ()
        {
            _dependency.Message("Indexmodel.OnGet created this message. ");
    }
  }
              

The IndexModel class creates and directly depends on the MyDependency. In the above example, there are following reasons we should avoid.

  • The IndexModel class must be modified and Mydependency replace with different implementation.
  • The MyDependency must be configured by IndexModel class. If a large project MyDependency class is depends by multiple class. It becomes scattered across the app.

These are problems throughDependency Injection:

  • The Dependency implementation use of an interface or base class to abstract in Dependency Injection.
  • Asp.Net Core provides built-in service provider that is IServiceProvider. If you add class it will offer services, always registered in the Startup.ConfigureServices method.

You can create interface IDependency and method, Message creates.

Example:

publicinterfaceIDependency
{
  voidMessage(string message);
}
              

In MyDependency, you applied to the interface.

Example:

publicclassMyDependency :IDependency
{
  publicvoidMessage(string message)
  {
    Console.WriteLine($"My Dependency.Message called. Message: {message}");
  }
}
              

Now you can add this class in Startup.ConfigureServices method.

Example:

publicvoidConfigureServices(IServiceCollection services)
        {
services.AddScoped();

              

Example:

publicclassIndex2Model: PageModel
{
  privatereadonlyIDependency _dependency;

  publicIndex2Model (IDependency dependency)
        {
            _dependency = dependency;
        }
  publicvoidOnGet ()
        {
            _dependency.Message("Working");
        }
}
              

The DI Pattern using in the controller.

  • You can only use the IDependency interface, where type is a concrete type of MyDependency. It makeschanges to implementation so easily and controller use it without modifying the controller.
  • You cannot create an instance of MyDependency, it`s in by default created DI container.

An implementation of interfaceIDependency can be improved by using the built-in logging API.

Example:

publicclassDependency2 :IDependency
    {
privatereadonlyILogger _logger;
publicDependency2(ILogger logger)
        {
            _logger = logger;
        }
publicvoidMessage(string message)
        {
            _logger.LogInformation($"Dependency method created Mesaage:{message}");
        }
    }
              

This code updated the ConfigureServices method and registers new IDependency implement.

Example:

publicvoidConfigureServices(IServiceCollection services)
{
  services.AddScoped();
  services.AddRazorPages();
}
              

Dependency2 depends on ILogger,This requestis calledthe constructor. It is a Framework-provided service.

ILogger is not unfamiliar to use Dependency Injection which is chained function. Every dependency requested in turn on its own dependencies request. The set of dependencies are collective that must be resolved typically and referred to as a dependency tree, dependency graph, or object graph.

In the container it resolves ILogger by taking advantage of generic open types, every generic constructed type is needed eliminating.

Dependency Injection terminology in a service.

  • IDependency service is typically an object that provides a service to other objects.
  • The web service is not related, although the service may use a web service.

Example:

publicclassDisplayModel :PageModel
    {
privatereadonlyILogger _logger;
publicDisplayModel(ILogger logger)
        {
            _logger = logger;
        }
publicstring Message { get; set; }

publicvoidOnGet()
        {
            Message = $"Display Page visited at {DateTime.UtcNow.ToLongTimeString() }";
            _logger.LogInformation(Message);
        }
    }
              

In this above code, you do not need to update in ConfigureServices, because logging is provided by the framework.

Services Injected into Startup


The Startup constructor and the Startup.Configure method can be injected into service.

There the following service is injected into the Startup constructor.

  • The IWebHostEnvironment service is providing with namespace using Microsoft.AspNetCore.Hosting.

  • The IHostEnvironment service is providing with namespace using Microsoft.Extensions.Hosting.

  • The IConfiguration service is providing with namespace using Microsoft.Extensions.Configuration.

You can add any service registered with a Dependency Injection container that can be injected into the Startup.Configure method.

Example:

publicvoidConfigure (IApplicationBuilder app,IWebHostEnvironmentenv,ILogger logger)
  {
     ….
  }
                

Understanding Service Lifetime


The lifetime of a registered service type is managed by Built-in IoC container. The Built-in IoC container automatically disposes of a service based on the specified lifetime.

There are three types of Built-in IoC container which provides lifetime support.

1) Singleton:-> A single instance of service throughout the applications’ lifetime to create and share in IoC container.

2) Transient:-> It will create a new instance of the specified type to every time you ask for it.

3) Scoped:-> It will create an instance of the specified service type once per request and it will share in a single request.

Looking to Hire ASP.Net Core Developer?
Contact Now

Example:

publicvoidConfigureServices(IServiceCollection services)
{
  services.Add(newServiceDescriptor(typeof(IDependency), newMyDependency())); //singleton

  services.Add(newServiceDescriptor(typeof(IDependency), typeof(MyDependency), ServiceLifetime.Transient)); //Transient

  services.Add(newServiceDescriptor(typeof(IDependency), typeof(MyDependency), ServiceLifetime.Scoped)); //Scoped

}
                

Extension Methods for Registration


AddSingleton(), AddTransient() and AddScoped() methods for singleton, transient and scoped lifetime respectively includes extensions methods of each types of lifetime.

Example:

publicvoidConfigureServices(IServiceCollection services)
{
  services.AddSingleton();
  services.Add(newServiceDescriptor(typeof(IDependency), newMyDependency())); //singleton

  services.AddTransient();
  services.Add(newServiceDescriptor(typeof(IDependency), typeof(MyDependency), ServiceLifetime.Transient)); //Transient

  services.AddScoped();
  services.Add(newServiceDescriptor(typeof(IDependency), typeof(MyDependency), ServiceLifetime.Scoped)); //Scoped

}
                

Constructor Injection


If you add a registered service and if a service type is included as a parameter in a constructor the IoC container automatically performs constructor.

Example:

publicclassLogController : Controller
    {
        ILogger _logger;

  publicLogController(ILogger logger)
        {
            _logger = logger;
        }

publicIActionResultIndex()
        {
            _logger.LogInformation("Executing /home/Index");

      returnView();
        }
}
                

In the preceding code, this container automatically passes an instance of MyDependency to the constructor of LogController. It will create and dispose an instance of ILogger based on the lifetime registration.

Action Method in Dependency Injection


We may only need dependency service type in a single action method. In the Action method, we can use the [FromService] attribute with the service type of parameter in the method.

Example:

usingMicrosoft.AspNetCore.Mvc;

publicclassLogController : Controller
    {
  publicLogController()
        {

        }
publicIActionResult Index([FromServices] ILogger logger)
        {
            _logger.LogInformation("Executing /home/Index");

returnView();
        }
}
                

Property in Dependency Injection


The property injection is not supported in a built-in IoC container. If the property injection use in your program you can use a third-party IoC container.

Service Get Manually


Iffew at times not required to include dependency service in the constructor. It can access dependent services dependent on built-in IoC container manually using HttpContext with RequestServices.

Example:

publicLogController()
        {

}
publicIActionResultIndex()

    {
  var service = this.HttpContext.RequestServices;
  var log = (ILogger)service.GetService(typeof(ILogger));
  log.LogInformation("Executing /home/Index");

  returnView()
}
                

Conclusion


When you add new any of functionality use like Entity Framework using Sql server so you can add this service in the ConfigureService method. It will access your project seamlessly.These classes are directly instantiating that base type, the new interface type and pass this type through the constructor or method.If we are practicing whilecreating dependency injection, sometime your existing code in one or more application will try to refactor used base type into interface.

Dependency Injection in Asp.Net Core What is Dependency Injection? Dependency Injection technique is used tocreate a maintainable code in .Net Core.The Dependency Injection provides extensive support in .Net Core, it depends onyou how to apply it. The class and their dependencies to achieve inversion of controlin dependency injection. A dependency is an object depends on another object. It is also called DI. The Dependency Injection provide loose coupling and promotes testability and maintenance. DI used to design pattern used implemented to IoC. There are three types of class in Dependency Injection pattern: 1. Client Class:-> This is dependent class it depends on service class. 2. Service Class:-> That class provides service to the client class in the service class. 3. Injector Class:-> It injects to the service class object into the client class. Overview of Dependency Injection You can understand the Dependency Inversion Principle so it is helpful before initiating Dependency Injection, it gives us the guidelines for loosely-coupled classes. Low level modules should depend on high-level modules and both are depending on abstractions. The details should depend upon abstractions but abstractions should not depend upon details. This is actually mechanism of you can use to make higher-level modules that depends on abstraction.You can create a class of MyDependency and create a Message method in Asp.Net Core. Example: publicclassMyDependency { publicvoidMessage (string message) { Console.WriteLine($"My Dependency.Message called. Message: {message} "); } } In the MyDependency.cs file, you can add another class, IndexModel and derived to PageModel and create a variable name of MyDependency. Create a new method of OnGet in this method you will pass theMydependency method. Read More:13 Important .net Core Libraries That Every .net Core Developer Should Know Example: publicclassIndexModel: PageModel { privatereadonlyMyDependency _dependency = newMyDependency (); publicvoidOnGet () { _dependency.Message("Indexmodel.OnGet created this message. "); } } The IndexModel class creates and directly depends on the MyDependency. In the above example, there are following reasons we should avoid. The IndexModel class must be modified and Mydependency replace with different implementation. The MyDependency must be configured by IndexModel class. If a large project MyDependency class is depends by multiple class. It becomes scattered across the app. These are problems throughDependency Injection: The Dependency implementation use of an interface or base class to abstract in Dependency Injection. Asp.Net Core provides built-in service provider that is IServiceProvider. If you add class it will offer services, always registered in the Startup.ConfigureServices method. You can create interface IDependency and method, Message creates. Example: publicinterfaceIDependency { voidMessage(string message); } In MyDependency, you applied to the interface. Example: publicclassMyDependency :IDependency { publicvoidMessage(string message) { Console.WriteLine($"My Dependency.Message called. Message: {message}"); } } Now you can add this class in Startup.ConfigureServices method. Example: publicvoidConfigureServices(IServiceCollection services) { services.AddScoped(); Example: publicclassIndex2Model: PageModel { privatereadonlyIDependency _dependency; publicIndex2Model (IDependency dependency) { _dependency = dependency; } publicvoidOnGet () { _dependency.Message("Working"); } } The DI Pattern using in the controller. You can only use the IDependency interface, where type is a concrete type of MyDependency. It makeschanges to implementation so easily and controller use it without modifying the controller. You cannot create an instance of MyDependency, it`s in by default created DI container. An implementation of interfaceIDependency can be improved by using the built-in logging API. Example: publicclassDependency2 :IDependency { privatereadonlyILogger _logger; publicDependency2(ILogger logger) { _logger = logger; } publicvoidMessage(string message) { _logger.LogInformation($"Dependency method created Mesaage:{message}"); } } This code updated the ConfigureServices method and registers new IDependency implement. Example: publicvoidConfigureServices(IServiceCollection services) { services.AddScoped(); services.AddRazorPages(); } Dependency2 depends on ILogger,This requestis calledthe constructor. It is a Framework-provided service. ILogger is not unfamiliar to use Dependency Injection which is chained function. Every dependency requested in turn on its own dependencies request. The set of dependencies are collective that must be resolved typically and referred to as a dependency tree, dependency graph, or object graph. In the container it resolves ILogger by taking advantage of generic open types, every generic constructed type is needed eliminating. Dependency Injection terminology in a service. IDependency service is typically an object that provides a service to other objects. The web service is not related, although the service may use a web service. Example: publicclassDisplayModel :PageModel { privatereadonlyILogger _logger; publicDisplayModel(ILogger logger) { _logger = logger; } publicstring Message { get; set; } publicvoidOnGet() { Message = $"Display Page visited at {DateTime.UtcNow.ToLongTimeString() }"; _logger.LogInformation(Message); } } In this above code, you do not need to update in ConfigureServices, because logging is provided by the framework. Services Injected into Startup The Startup constructor and the Startup.Configure method can be injected into service. There the following service is injected into the Startup constructor. The IWebHostEnvironment service is providing with namespace using Microsoft.AspNetCore.Hosting. The IHostEnvironment service is providing with namespace using Microsoft.Extensions.Hosting. The IConfiguration service is providing with namespace using Microsoft.Extensions.Configuration. You can add any service registered with a Dependency Injection container that can be injected into the Startup.Configure method. Example: publicvoidConfigure (IApplicationBuilder app,IWebHostEnvironmentenv,ILogger logger) { …. } Understanding Service Lifetime The lifetime of a registered service type is managed by Built-in IoC container. The Built-in IoC container automatically disposes of a service based on the specified lifetime. There are three types of Built-in IoC container which provides lifetime support. 1) Singleton:-> A single instance of service throughout the applications’ lifetime to create and share in IoC container. 2) Transient:-> It will create a new instance of the specified type to every time you ask for it. 3) Scoped:-> It will create an instance of the specified service type once per request and it will share in a single request. Looking to Hire ASP.Net Core Developer? Contact Now See here Example: publicvoidConfigureServices(IServiceCollection services) { services.Add(newServiceDescriptor(typeof(IDependency), newMyDependency())); //singleton services.Add(newServiceDescriptor(typeof(IDependency), typeof(MyDependency), ServiceLifetime.Transient)); //Transient services.Add(newServiceDescriptor(typeof(IDependency), typeof(MyDependency), ServiceLifetime.Scoped)); //Scoped } Extension Methods for Registration AddSingleton(), AddTransient() and AddScoped() methods for singleton, transient and scoped lifetime respectively includes extensions methods of each types of lifetime. Example: publicvoidConfigureServices(IServiceCollection services) { services.AddSingleton(); services.Add(newServiceDescriptor(typeof(IDependency), newMyDependency())); //singleton services.AddTransient(); services.Add(newServiceDescriptor(typeof(IDependency), typeof(MyDependency), ServiceLifetime.Transient)); //Transient services.AddScoped(); services.Add(newServiceDescriptor(typeof(IDependency), typeof(MyDependency), ServiceLifetime.Scoped)); //Scoped } Constructor Injection If you add a registered service and if a service type is included as a parameter in a constructor the IoC container automatically performs constructor. Example: publicclassLogController : Controller { ILogger _logger; publicLogController(ILogger logger) { _logger = logger; } publicIActionResultIndex() { _logger.LogInformation("Executing /home/Index"); returnView(); } } In the preceding code, this container automatically passes an instance of MyDependency to the constructor of LogController. It will create and dispose an instance of ILogger based on the lifetime registration. Action Method in Dependency Injection We may only need dependency service type in a single action method. In the Action method, we can use the [FromService] attribute with the service type of parameter in the method. Example: usingMicrosoft.AspNetCore.Mvc; publicclassLogController : Controller { publicLogController() { } publicIActionResult Index([FromServices] ILogger logger) { _logger.LogInformation("Executing /home/Index"); returnView(); } } Property in Dependency Injection The property injection is not supported in a built-in IoC container. If the property injection use in your program you can use a third-party IoC container. Service Get Manually Iffew at times not required to include dependency service in the constructor. It can access dependent services dependent on built-in IoC container manually using HttpContext with RequestServices. Example: publicLogController() { } publicIActionResultIndex() { var service = this.HttpContext.RequestServices; var log = (ILogger)service.GetService(typeof(ILogger)); log.LogInformation("Executing /home/Index"); returnView() } Conclusion When you add new any of functionality use like Entity Framework using Sql server so you can add this service in the ConfigureService method. It will access your project seamlessly.These classes are directly instantiating that base type, the new interface type and pass this type through the constructor or method.If we are practicing whilecreating dependency injection, sometime your existing code in one or more application will try to refactor used base type into interface.
Kapil Panchal

Kapil Panchal

A passionate Technical writer and an SEO freak working as a Content Development Manager at iFour Technolab, USA. With extensive experience in IT, Services, and Product sectors, I relish writing about technology and love sharing exceptional insights on various platforms. I believe in constant learning and am passionate about being better every day.

Build Your Agile Team

Enter your e-mail address Please enter valid e-mail

Categories

Ensure your sustainable growth with our team

Talk to our experts
Sustainable
Sustainable
 
Blog Our insights
10 Executive Dashboard Examples for Consultants and CEOs
10 Executive Dashboard Examples for Consultants and CEOs

There is a principle behind every business. “If you don’t keep track of essentials, you won’t get clear direction, eventually causing your company to stumble.” To manage this scenario,...

How Spatial Data Analysis Improves Healthcare
How Spatial Data Analysis Improves Healthcare

Do you know when geospatial analysis took traction in healthcare? It was when John Snow, a London-based physician, used it to analyze the spread of cholera, which ultimately proved...

4 Types of Power BI Dashboards: Analytical, Strategic, Operational, and Tactical
4 Types of Power BI Dashboards: Analytical, Strategic, Operational, and Tactical

One interesting aspect you truly love about Power BI, as a CTO, is how it lets you step back and see the bigger picture of your business. Isn’t it? Without getting bogged down in minute...