ASP.MVC 6 Features - Dependency Injection

In the version prior to MVC 6 it's possible to do Dependency Injection(DI) using third party libraries like AutoFac. But in MVC 6, DI is built into right into the framework. All the libraries like MVC, WebAPI, SignalR are making use of this minimalistic DI container. The core features of the container are exposed through the IServiceProvider interface and since it's available and same for all the components of the framework, a single dependency can be resolved from any part of the application.

Let's see an example of DI in action in MVC 6

First of all I'm going to create an interface and concrete class for a repository to deal with the domain entity.

Interface

namespace samplemvc.Repository
{
    public interface ISampleRepository
    {
        string GetMessage();
        
    }
}

Implementation

namespace samplemvc.Repository
{
    public class SampleRepository : ISampleRepository
    {
        public string GetMessage()
        {
            return GetHashCode().ToString();
        }
    }
}

I am using the GetHashCode function in the GetMessage() which returns a unique number for a .NET instance. Now let's go to the controller to inject two instances of our repository into it. I will use these two instances to show how MVC is handling the creation of multiple instances of our dependency.

Controller

        private readonly ISampleRepository _repo1;
        private readonly ISampleRepository _repo2;

        public HomeController(ISampleRepository repo1, ISampleRepository repo2)
        {
            _repo1 = repo1;
            _repo2 = repo2;
        }

So here I've created a constructor for the controller which expects two objects of  ISampleRepository to be supplied and sets that to readonly variables defined in the code. If we run our code at this moment, we will get an exception saying that 

Unable to resolve service for type 'samplemvc.Repository.ISampleService' while attempting to activate 'samplemvc.Controllers.HomeController'.

To resolve this we need to tell the DI contianer how to create an instance for our repository. This can be done from the ConfigureServices method in startup.cs file

public void ConfigureServices(IServiceCollection services)
        {
         
            services.AddMvc();

            // our DI mapping
            services.AddInstance<ISamplerepository>(new SampleRepository());
        }

Here we are indicating to DI container that whenever there is a need for ISampleRepository, create a new instance of SampleRepository. DI container supports 4 modes such as

  1. Instance
  2. Transient
  3. Singleton
  4. Scoped

Here we are using the Instance mode so that the responsiblity of object creation is with us and are doing it by calling the new SampleRepository(). 

Let's complete the action method in the controller and view for displaying the data

Action Method

 public IActionResult Sample()
        {
            ViewBag.Message1 = _repo1.GetMessage();
            ViewBag.Message2 = _repo2.GetMessage();

            return View();
        }

View

<br/>
<br/>
<label>Message 1</label>
<label>@ViewBag.Message1</label>

<label>Message 2</label>
<label>@ViewBag.Message2</label>


If we run our application now, you will get the output like the one shown below

You can see that both the messages are showing the same number because there's only one instance being created and GetHashCode returns the unique number of that instance.

I will explain the use of other modes in the next post, till then Happy Coding !!!


No Comments

Add a Comment