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
- Instance
- Transient
- Singleton
- 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
Connecting Azure Blob Storage account using Managed Identity
Posted 12/9/2022Securing Azure KeyVault connections using Managed Identity
Posted 11/26/2022Manage application settings with Azure KeyVault
Posted 11/9/2022Adding Serilog to Azure Functions created using .NET 5
Posted 4/3/2021Learn how to split log data into different tables using Serilog in ASP.NET Core
Posted 4/23/2020