What Is Dependency Injection? :
A container or an object which creates and passes the dependant object in an application is called Dependency Injection. In simple words instead of creating dependant objects manually by a programmer, objects are get created by library container which normally handles both the creation and garbage handling. Normally the objects are injected by a mechanism like Property Injection and Constructor Injection(constructor inject most widely used mechanism).
From .NET Core, we are getting Dependency Injection as a default feature. With the evolution of .NET Core Microsoft has implemented much more efficient ways of injecting approaches like Constructor Injection, Razor Page Injection(.cshml), and Controller Action Methods Injection(Using Microsoft.AspNetCore.Mvc.FromServices Attribute class).
Here I'm going to explain about Controller Action Methods Injection working mechanism comparing with traditional Constructor Injection.
A Brief Look At Constructor Injection:
Now let's go through Constructor Injection as follows
Sample Controller:
public class VehicleController : Controller { private readonly IVehicleLogic _vehicleLogic; public VehicleController(IVehicleLogic vehicleLogic) { _vehicleLogic = vehicleLogic; } public IActionResult GetAllVehicle() { _vehicleLogic.DoSomething(); return Ok(); } }Here we can observe the built-in Microsoft Dependency Injection container creates the object for 'IVehicleLogic' and passed to the constructor of the controller. So on every request to the 'VehicleController' initialized with 'IVehicleLogic' object passed to its constructor and then 'IVehcleLogic' object will be used by Action methods to carry out their respective functionalities.
In a large application, most of the cases controller gets injected more than one object as follows.
Sample Controller With Multiple Object Injecting:
public class VehicleController : Controller { private readonly IVehicleLogic _vehicleLogic; private readonly ISparePartsLogic _sparePartsLogic; private readonly IPaymentsLogic _paymentsLogic; public VehicleController( IVehicleLogic vehicleLogic, ISparePartsLogic sparePartsLogic, IPaymentsLogic paymentsLogic) { _vehicleLogic = vehicleLogic; _sparePartsLogic = sparePartsLogic; _paymentsLogic = paymentsLogic; } [HttpGet] [Route("allvehicles")] public IActionResult GetAllVehicle() { _vehicleLogic.DoSomething(); return Ok(); } [HttpGet] [Route("vehicle-spare-parts")] public IActionResult GetVehicleSapareParts() { _sparePartsLogic.GetVehicleSpareParts(); return Ok(); } [HttpGet] [Route("vehicle-payments")] public IActionResult GetVehiclePayment() { _paymentsLogic.VehicleCost(); return Ok(); } }
- Now observe the above sample on every request to this controller get initialized by getting input parameters of 'IVehicleLogic', 'ISparePartsLogic' and 'IPaymentLogic' objects from Dependency injector.
- So on every request, there will be some unused objects created because of the constructor injection this doesn't mean leads to performance issues. It is also not a bad code to injecting all objects in the constructor injection. More probably based on your coding style and patterns these object numbers will more or less.
- We may think we can create single business logic for a single controller to avoid unused object creation, it may not be a bad idea but some times it leads to more code.
- But this can be avoided by using Dependency Injection On Controller Action Method(will be explained in the below steps).
Dependency Injection In Controller Action Method:
Using Microsoft.AspNetCore.Mvc.FromServices we can inject an object to the action method as follows.
public class VehicleController : Controller { [HttpGet] [Route("allvehicles")] public IActionResult GetAllVehicle([FromServices] IVehicleLogic vehicleLogic) { vehicleLogic.DoSomething(); return Ok(); } [HttpGet] [Route("vehicle-spare-parts")] public IActionResult GetVehicleSapareParts([FromServices] ISparePartsLogic sparePartsLogic) { sparePartsLogic.GetVehicleSpareParts(); return Ok(); } [HttpGet] [Route("vehicle-payments")] public IActionResult GetVehiclePayment([FromServices] IPaymentsLogic paymentsLogic) { paymentsLogic.VehicleCost(); return Ok(); } }Here observe injected the business logic from action methods using [FromServices] attribute, also we can see nothing is injected from the constructor. In this case, we have avoided all unused object injection from the constructor.
An action method can inject N number of objects as follows.
[HttpGet] [Route("vehicle-payments")] public IActionResult GetVehiclePayment( [FromServices] IVehicleLogic vehicleLogic, [FromServices] IPaymentsLogic paymentsLogic) { paymentsLogic.VehicleCost(); return Ok(); }
Based on your coding design pattern and structure if we want we can use both constructor injection and action method injection as follows.
Both Constructor And Action Method Injection Sample:
public class VehicleController : Controller { private readonly IVehicleLogic _vehicleLogic; public VehicleController(IVehicleLogic vehicleLogic) { _vehicleLogic = vehicleLogic; } [HttpGet] [Route("allvehicles")] public IActionResult GetAllVehicle() { _vehicleLogic.DoSomething(); return Ok(); } [HttpGet] [Route("vehicle-spare-parts")] public IActionResult GetVehicleSapareParts([FromServices] ISparePartsLogic sparePartsLogic) { _vehicleLogic.DoSomething(); sparePartsLogic.GetVehicleSpareParts(); return Ok(); } [HttpGet] [Route("vehicle-payments")] public IActionResult GetVehiclePayment([FromServices] IPaymentsLogic paymentsLogic) { _vehicleLogic.DoSomething(); paymentsLogic.VehicleCost(); return Ok(); } }Here we can observe 'IVehicleLogic' injected from constructor since it was consumed by every action method.
Wrapping Up:
Hopefully, this article will help to understand the Controller Action Method Dependency Injection. I love to have your feedback, suggestions and better techniques in the comment section.
Comments
Post a Comment