Tag - .Net-Core-3.1

Dependency Injection with Example
Jun 12, 2024

What is the Dependency Injection Design Pattern? Dependency Injection is a design pattern used to execute Inversion of control (IoC). It is a process of injecting the dependency object into a class that depends on it. Dependency Injection is the often-used design pattern these days to separate the dependencies between the objects that allow us to implement loosely coupled software components. It allows the making of dependent objects outside of the class and supplies those objects to a class in distinct ways. Let’s talk about the bit-by-bit process to implement dependency Injection in the ASP.Net Core application. The ASP.NET Core Framework provides inbuilt support for Dependency Injection design patterns. It injects the dependency objects to a class via a constructor, method, or property using the built-in IoC container. The inbuilt IoC container is elected by IServiceProvider implementation, which supports default construction injection. The classes managed by built-in IoC Containers are called services.   Types of Services in ASP.NET Core There are 2 types of services in ASP.NET core. Framework Services: Services that are a part of the ASP.NET core framework, like IApplicationBuilder, IHostingEnvironment, ILoggerFactory, etc. Application Services: The services you create as a programmer for your application. Before registering services, let’s first know the different methods to register a service. The ASP.NET core gives 3 methods to register a service with a Dependency Injection container. The method that we use to register a service will determine the lifetime of the service. Singleton: A Singleton service is created only once per application lifetime. The same instance is used all over the application. Common uses contain configuration services, logging, or other services where a single instance is enough and advisable. Since the same instance is used throughout, you need to ensure that Singleton services are thread-safe. Not suitable for saving user-specific data or request-specific data. This can be reached by adding the service as a singleton through the AddSingleton method of the IServiceCollection. Transient: A Transient service is created every time it is requested from the service container. This means that a new instance is provided to every class or method that requires it. Suitable for lightweight, stateless services. Since a new instance is created every time, you don’t need to worry about thread safety related to the internal state. While transient services are simple and provide clean separation, they can be more resource-intensive if they are vast or require significant resources to build. This can be got by adding the service through the AddTransient method of the IServiceCollection. Scoped: A scoped service is created once per client request (means per HTTP request). Perfect for services that need to maintain state within a single request but should not be shared across different requests. This can be achieved by adding the service through the AddScoped method of the IServiceCollection.   How to Register a Service with ASP.NET Core Dependency Injection Container? We need to register a service to the in-built dependency injection container with the program class.  The below code shows how to register a service with different lifetimes. var builder = WebApplication.CreateBuilder(args); // ADD FRAMEWORK MVC SERVICES TO THE CONTAINER builder.Services.AddMvc(); // ADD APPLICATION SERVICES TO THE CONTAINER builder.Services.Add(new ServiceDescriptor(typeof(ISubjectTypesDA), new SubjectTypesDA())); // BY DEFAULT SINGLETON builder.Services.Add(new ServiceDescriptor(typeof(ISubjectTypesDA), new SubjectTypesDA(),ServiceLifetime.Singleton)); // SINGLETON builder.Services.Add(new ServiceDescriptor(typeof(ISubjectTypesDA), new SubjectTypesDA(),ServiceLifetime.Transient)); // TRANSIENT builder.Services.Add(new ServiceDescriptor(typeof(ISubjectTypesDA), new SubjectTypesDA(),ServiceLifetime.Scoped)); // SCOPED   What is the ServiceDescriptor class in .NET Core? This class speaks for a descriptor of a service in the DI Container. It essentially describes how to service should be instantiated and managed by the container. So, it describes a service, including its lifetime, the service type, and the implementation type. Extension methods for Registration ASP.NET Core framework contains extension methods for each type of lifetime: AddSingleton, AddTransient, and AddScoped methods.  The below example shows how to register types of lifetimes using extension methods. // ADD APPLICATION SERVICE TO THE CONTAINER. services.AddTransient<IEmailSenderBL, EmailSenderBL>(); // TRANSIENT services.AddScoped<ISubjectTypesBL, SubjectTypesBL>(); // SCOPED services.AddSingleton<ICPCalculationBL, CPCalculationBL>(); // SINGLETON   The dependent class is a class which depends on the dependency class. The dependency class is a class that provides service to the dependent class. The interface injects the dependency class object into the dependent class.   There are 3 types of Dependency Injection. Constructor Injection Property Injection Method Injection   Constructor Injection: we register the service, the IoC automatically executes constructor injection if a service type is included as a parameter in a constructor. Example: public class CenterController : BaseController { private ICenterBL _centerBL; public CenterController(ICenterBL centerBL) : base(myLoginUser) { _centerBL = centerBL; } [Authorize] public IActionResult Index() { try { var data = _centerBL.GetCenterpageList(); return View(data); } catch (Exception EX) { throw EX; } } }   Property Injection: Not required to add dependency services in the constructor. We can manually access the services configured with built-in IoC containers using the RequestServices property of HttpContext.   public class AddressController : Controller { [Authorize] public IActionResult Index() { var services = this.HttpContext.RequestServices; IAddressBL _address = (IAddressBL)services.GetService(typeof(IAddressBL)); var data = _address.GetAddressList(); return View(data); } }   Method Injection: Occasionally, we may only need a dependency object in a single action method. In that case, we need to use the [FromServices] attribute with the service type parameter in the action method. In the below example, you can see we are using the [FromServices] attribute within the Index action method. So, at runtime, the IoC Container will inject the dependency object to the IAddressBL repository reference variable. As we inject the dependency object through a method, it is called method dependency injection. public class CommonController: Controller { public IActionResult Index([FromServices] IAddressBL _addressBL) { var list = _addressBL.GetAddressList(); return View(list); } } Advantages of Dependency Injection Loose Coupling: we can separate our classes from their dependencies. This results in code that is simpler to maintain and test. Testability: we can increase the testability of our code since we can easily replace dependencies with mock objects during unit testing. Extensibility: enhance the extensibility of our code by offering the flexibility to switch out dependencies conveniently. Reusability: makes our code more reusable since we can conveniently share dependencies among various classes.  

magnusminds website loader