ASP.NET Core Dependency Injection

In this article, I am going to discuss the ASP.NET Core Dependency Injection with an example.  The Dependency Injection Design Pattern is one of the most used design Patterns in real-time applications. But the good thing is that ASP.NET Core Provides inbuilt support for Dependency Injection.

What is Dependency Injection?

The Dependency Injection a process of injecting the object of a class into a class that depends on it. The Dependency Injection is the most commonly used design pattern nowadays to remove the dependencies between the objects. So, the Dependency Injection design pattern allows us to develop loosely coupled software components. ASP.NET Core is designed from scratch to support Dependency Injection. ASP.NET Core injects objects of dependency classes through constructor or method by using built-in IoC container.

Let us discuss the step by step procedure to implement dependency injection in ASP.NET Core Web Api application.

Step 1: Open Visual Studio and create a new project and Select API as template and press OK.

Step 2: In this section I am going to show you how you can use Dependency Injection for getting the Categories. So lets first Create Folder for Models and Create a Class Category in that Model Folder.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace DependencyInjection.Model
{
    public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
    }
}

Step 3: After that Create an interface of repository having GetCategories method which returns the list of category object jut like below.

using DependencyInjection.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace DependencyInjection.Interface
{
    public interface ICategoryRepository
    {
        List<Category> GetCategories();
    }
}

Step 4: Implement the preceding interface and return some sample data. As our target is to understand dependency injection, here, we are not going to fetch the data from database rather returning hard coded ones.

using DependencyInjection.Interface;
using DependencyInjection.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace DependencyInjection.Repository
{
    public class CategoryRepository : ICategoryRepository
    {
        public List<Category> GetCategories()
        {
            List<Category> categories = new List<Category>();

            Category category = new Category() { CategoryId = 1, CategoryName = "Sweets" };
            categories.Add(category);

            category = new Category() { CategoryId = 2, CategoryName = "Snakcs" };
            categories.Add(category);

            return categories;
        }
    }
}

Assume that we are not aware of the dependency injection. Then, how will we get the data from API? We need to create an instance of CategoryRepository and call the GetCategories method using that instance. So in future, if there is a change in CategoryRepository it will directly affect the GET method of API as it is tightly coupled with that. So in this case we use Dependency Injection because as we want to get the Categories we directly call the interface and If a class implement that interface then that class returns the data. And in future if there is slight change in the database or in the class it does not affect our controller code because our controller code is dependent on the interface not on that Class which return the data. If in future we want to change the Database connectivity like currently i am getting the data from SQL database and I use entity framework core and after sometime I want to change the Database from SQL to Oracle then it only affect our repository class not our controller code. Hence for these things we use Dependency Injection.

Dependency Lifetimes

With the .NET Framework, we used to use containers like LightInject, NInject, Unity etc. But in .NET Core, Microsoft has provided an in-built container. We need to add the namespace, i.e., Microsoft.Extension.DependencyInjection.So, in the startup class, inside the ConfigureServices method, we need to add our dependency into the service collection which will dynamically inject whenever and wherever we want in the project. Also, we can mention which kind of instance we want to inject – the lifetime of our instance.

At registration time, dependencies require a lifetime definition. The service lifetime defines the conditions under which a new service instance will be created. Below are the lifetimes defined by the ASP.Net DI framework. The terminology may be different if you choose to use a different framework.

  • Transient – Created every time they are requested
  • Scoped – Created once per scope. Most of the time, scope refers to a web request. But this can also be used for any unit of work, such as the execution of an Azure Function.
  • Singleton – Created only for the first request. If a particular instance is specified at registration time, this instance will be provided to all consumers of the registration type.

Lets add the code in the Startup.cs class for configuring the Interface and that class which implement that interface by using any of the three method mentioned above according to our requirement.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DependencyInjection.Interface;
using DependencyInjection.Repository;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace DependencyInjection
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddTransient<ICategoryRepository, CategoryRepository>();  

            services.AddSingleton<ICategoryRepository, CategoryRepository>();

            //services.AddScoped<ICategoryRepository, CategoryRepository>();  
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }
}

So far, we have added our dependency to the collection. Now, it’s time to inject where we need it, i.e., in the Web API. Our GET method is inside the CategoryController and we want an instance of categoryrepository. So, let’s create a constructor of CategoryController which expects the type of ICategoryRepository. From this parameterized constructor, set the private property of type ICategoryRepository which will be used to call GetCategories from the GET method.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DependencyInjection.Interface;
using DependencyInjection.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace DependencyInjection.Controllers
{
    [Route("api/Category")]
    [ApiController]
    public class CategoryController : ControllerBase
    {
        private ICategoryRepository categoryRepository { get; set; }
        public CategoryController(ICategoryRepository categoryRepository)
        {
            this.categoryRepository = categoryRepository;
        }

        [HttpGet]
        public async Task<IActionResult> Get()
        {
            List<Category> categories = categoryRepository.GetCategories();
            return Ok(categories);
        }
    }
}

Run the application and we will be able to see the result of the GET method of CategoryController. Now, even though we haven’t created an instance of CategoryRepository which is expected by CategoryController, we are able to call the GET method successfully. The instance of CategoryRepository has been resolved dynamically through Dependency Injection.

0 0 vote
Article Rating

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x