×
iFour Logo

Dependency Injection in Asp.Net Core

iFour Team - October 27, 2020

Listening is fun too.

Straighten your back and cherish with coffee - PLAY !

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 Table of Content 1. What is Dependency Injection? 2. Overview of Dependency Injection 3. Services Injected into Startup 4. Understanding Service Lifetime 5. Extension Methods for Registration 6. Constructor Injection 4. Action Method in Dependency Injection 5. Property in Dependency Injection 6. Service Get Manually 10. Conclusion 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.

Categories

Ensure your sustainable growth with our team

Talk to our experts
Sustainable
Sustainable
 

Blog Our insights

Node.js 19 - What changes and effects does it bring to the business?
Node.js 19 - What changes and effects does it bring to the business?

Table of Content 1.What is Node.js? 2.Introducing Node.js 19 with major updates and changes 3.Why should I upgrade from Node 18 to 19? 4.New Features in Node.js...

What are the concerns faced while developing Fitness management software?
What are the concerns faced while developing Fitness management software?

Table of Content 1.Explaining vision to folklores 2.Changing the habits of end users 3.Conflicts with team members 4.The issue of cyber security 5.Identifying issues...

How Blockchain can impact the Financial industry in 2023?
How Blockchain can impact the Financial industry in 2023?

Table of Content 1.Boosts payment transparency, trust, and efficiency 2.Reduces operational risks and enables real-time verification 3.Eliminates central authority to...