ASP.NET Core

Dependency Injection in ASP.NET Core

Dependency Injection in ASP.NET Core

Dependency Injection in ASP.NET Corev

Dependency Injection (shortform “DI”) is an ASP.NET Core technique to achieve loosely coupling between objects so that the applications can be maintained in an easy manner.
Here DOT NET runtime engine automatically injects objects of dependency classes, mainly through the constructor of the Controllers. Thus making the job of the developer much easier.

Create an Asp.Net Core Web App (Model-View-Controller)


Model

public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}



Repositories
Ceate an Interface inside the Repositoryy folder and call it IRepository

public interface IRepository
{
    IEnumerable<Product> Products { get; }
    Product this[string name] { get; }
    void AddProduct(Product product);
    void DeleteProduct(Product product);
}


Create a Service Class Repository that implementn above interface IRepository

public class Repository : IRepository
{
    private Dictionary<string, Product> products;
    public Repository()
    {
        products = new Dictionary<string, Product>();
        new List<Product> {
            new Product { Name = "Men Shoes", Price = 111M },
            new Product { Name = "Shirts", Price = 32.00M },
            new Product { Name = "Pants", Price = 42.5M }
        }.ForEach(p => AddProduct(p));
    }

    public IEnumerable<Product> Products => products.Values;
    public Product this[string name] => products[name];
    public void AddProduct(Product product) => products[product.Name] = product;
    public void DeleteProduct(Product product) => products.Remove(product.Name);
}



Controller - Without Dependency Injection:

public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View(new Repository().Products);

// OR
Repository repository = new Repository();
List<Product> allProducts = repository.Products();
return View(allProducts);
    }
}



View

@if (ViewData.Count > 0)
{
    <table class="table table-bordered table-sm table-striped">
        @foreach (var kvp in ViewData)
        {
            <tr><td>@kvp.Key</td><td>@kvp.Value</td></tr>
        }
    </table>
}
<table class="table table-bordered table-sm table-striped">
    <thead>
        <tr><th>Name</th><th>Price</th></tr>
    </thead>
    <tbody>
        @if (Model == null)
        {
            <tr><td colspan="3" class="text-center">No Data Found!</td></tr>
        }
        else
        {
            @foreach (var p in Model)
            {
                <tr>
                    <td>@p.Name</td>
                    <td>@string.Format("{0:C2}", p.Price)</td>
                </tr>
            }
        }
    </tbody>
</table>



What is the Problem in the above implementation?

If you see the Controller’s code above you will find it is Tightly Coupled to the Repository.cs class. The reason being that we are directly creating the object of Repository class using new keyword.
Suppose after some time a need arises to change the repository to another class called DbRepository.cs. So we will have to change the Controller’s code like this:

public IActionResult Index()
{
    return View(new DbRepository().Products);
}

This is a problem of managing Tightly Coupled Components.


Why is tightly coupled code bad?
- It gives problems during the maintenance phase of the project. If one component changes then it will affect the other components also.
- There will be lots of problems when performing the Unit Testing of these components.


How DI Resolve this Issue?
- The Dependency Injection (DI) technique can solve these problems.
- The Controller class can be provided with the repository object automatically by ASP.NET Core and this will remove the tighlty coupling problem.


Implementing Dependency Injection in Above Controller
There are 2 steps to implement
1. Decouple the controller from the tiglht-coupled to loosely-coupled dependency.
2. Specifty how this new depenency (loosely-coupled) should be resolved by ASP.NET Core runtime.


// First Create loosely-coupled dependency in the controller.
// For this we will implement an Interface and use this Interface (instead of the Repository class) in the Controller

public class HomeController : Controller
{
// A variable of the Interface type (i.e IRepository) in your controller.
    private IRepository repository;
// Added a constructor that has a parameter of this interface type.
// Inside the constructor we have set the value of the interface variable to the value of the constructor’s parameter.
    public HomeController(IRepository repo)
    {
        repository = repo;
    }

    public IActionResult Index()
    {
// Now We can access the products using the Products property of the Interface.
        return View(repository.Products);
    }
}

With this we have added the loosely coupled dependency in the controller. If in future the need arises to change the repository then all you have to do is to create a new repository. We will not have to do a single change in the controller as it is now loosely-coupled to the repository.


One Last Change in Program.cs file
We have to tell ASP.NET Core how it should resolve the dependency of IRepository interface.

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        builder.Services.AddTransient<IRepository, Repository>();

        var app = builder.Build();  
        app.Run();
    }
}

This service will now be created in Transient manner, such that whenever a request for “IRepository” object is made then it should be resolved by providing implementation of “Repository” type. The first parameter of AddTransient method is of type interface (here IRepository) while the second type being the implementation class (here Repository.cs).






Related Post

About Us

Community of IT Professionals

A Complete IT knowledgebase for any kind of Software Language, Development, Programming, Coding, Designing, Networking, Hardware and Digital Marketing.

Instagram