Here, I am going to explain how to implement dependency injection in MVC project, including separate layers for getting data through Services and Repositories.
Step 1
Open Visual Studio, go to File->New->Project.
Step 2
Select “Web” from the left menu, “ASP.NET Web Application (.NET Framework)” from Project types list, and give some name to the application (I am naming it as DI).
Step 3
Select “Empty” template, check MVC Checkbox below, and click “OK”.
It will take a little time to create the solution.
Step 4
Open Solution Explorer, it will create the folder structure as shown below.
Step 5
Now we are going to create DAL (Data Access Layer), where data is available, Right Click on Solution Explorer, Goto Add->New Project…
Step 6
Select “Windows” from the left menu, “Class Library” from Project list, give some name (DAL), and click OK.
Step 7
“Class1.cs” will be opened.
Right click on Class1.cs in Solution Explorer and click “Rename”.
Rename it as “Customer”, one pop-up will be shown immediately. Click “Yes” (This will rename the file in all places).
Step 8
Now, paste the below code in Customer.cs class.
- namespace DAL
- {
- public class Customer
- {
- public int CustomerId { get; set; }
- public string CustomerName { get; set; }
- public string City { get; set; }
- }
- }
Here, we are creating CustomerId, CustomerName and City, the properties of the Customer Class.
Step 9
Now, right click on Solution Explorer, Go to Add->Class…
Step 10
Select “Interface”, Name it as “ICustomerRepository.cs”.
Step 11
Paste the below code in “ICustomerRepository.cs” interface.
- using System.Collections.Generic;
-
- namespace DAL
- {
- public interface ICustomerRepository
- {
- List<Customer> GetCustomers();
- }
- }
Here, we have defined one method GetCustomers() which will return the list of customers with defined properties in Customer.cs file.
Step 11
Now again, right click on Solution Explorer, Go to Add->Class…, Name it as “CustomerRepository.cs”.
Step 12
Paste the below code in “CustomerRepository.cs”.
- using System.Collections.Generic;
-
- namespace DAL
- {
- public class CustomerRepository : ICustomerRepository
- {
- public List<Customer> GetCustomers()
- {
- return new List<Customer>(){
- new Customer { CustomerId = 1, City = "Visakhapatnam", CustomerName = "Tulasi" },
- new Customer { CustomerId = 2, City = "Hyderabad", CustomerName = "Ramana" },
- new Customer { CustomerId = 3, City = "Bangalore", CustomerName = "Bablu" },
- new Customer { CustomerId = 4, City = "Chennai", CustomerName = "Brammaji" },
- };
- }
- }
- }
“CustomerRepository.cs” is implementing “ICustomerRepository.cs” interface, since “ICustomerRepository.cs” is having GetCustomers() method, it should be implemented in this class.
For time being, I am hardcoding Customer data, in real time we will be calling “dbContext” if using entity framework, Stored procedures for ADO.NET..etc.
Now, DAL Layer has completed.
Let’s go and create Service Layer.
Step 13
In Solution Explorer, right-click and Add->New Project.
Step 14
Select “Windows” from the left menu, “Class Library” from Project list, give a name as “Services”, click on OK.
Step 15
Now, Right-click on Class1.cs->Rename.
Rename it as “ICustomerService”, one pop will be shown immediately. Click Yes.
Step 16
Now change “Class” to interface, have the same method which is there in “ICustomerRepository.cs” file.
It will ask for reference once we move the cursor to redline and press “ctrl+.”, add the reference by clicking, “using DAL;(from DAL)” option.
Step 17
Paste the below code in ICustomerService.cs
- using DAL;
- using System.Collections.Generic;
-
- namespace Services
- {
- public interface ICustomerService
- {
- List<Customer> GetCustomers();
- }
- }
This interface has the same methods which are defined in DAL interface ie. “ICustomerRepository.cs”
Step 18
Now again right click on Solution Explorer, Goto Add->Class…, Name it as “CustomerService.cs”
Step 19
Paste the below code in “CustomerService.cs”
- using System.Collections.Generic;
- using DAL;
-
- namespace Services
- {
- public class CustomerService : ICustomerService
- {
- private ICustomerRepository _iCustomerRepository;
-
- public CustomerService(ICustomerRepository iCustomerRepository)
- {
- _iCustomerRepository = iCustomerRepository;
- }
- public List<Customer> GetCustomers()
- {
- return _iCustomerRepository.GetCustomers();
- }
- }
- }
Explantaion
Here “CustomerService.cs” class is implementing “ICustomerService.cs” interface. So actual data is available in “CustomerRepository.cs”, so we should not create object for “CustomerRepository.cs” and access the GetCustomers method as below.
- public List<Customer> GetCustomers()
- {
- CustomerRepository customerRepository = new CustomerRepository();
- return customerRepository.GetCustomers();
- }
This is wrong because of the compile time itself, we will know which class object is creating i.e. this violates the dependency injection concept.
We have to inject the interface, runtime and whatever class we mapped will be created and call the respective methods by using interface variable.
Here we are injecting interface variable from class constructor. So which class is implementing this interface will be known only inruntime.
- public CustomerService(ICustomerRepository iCustomerRepository)
Now DAL and Services layers are ready.
Step 20
Dependency injection can be implemented by using different frameworks like Ninject, Unity, Autofac, SturctureMap..etc.
Here we are implementing using Unity.
Now Right click on MVC application, Click on “Manage NuGet Packages...”
Step 21
NuGet package manager will be opened
Step 22
Click on Browse, type “unity.mvc” in search box, select Unity.Mvc5 package.
Step 23
Click “Install” button to complete the installation into web project.
One pop up will appear for the package acceptance, click “IAccept”
It will take some time for installation.
Once the installation is completed, it will open the readme.txt file.
Read the file to understand how it works.
Will have to just follow the steps mentioned in this text file.
Step 24
Open Global.asax file and paste the below code.
- using System.Web.Mvc;
- using System.Web.Routing;
-
- namespace DI
- {
- public class MvcApplication : System.Web.HttpApplication
- {
- protected void Application_Start()
- {
- AreaRegistration.RegisterAllAreas();
- RouteConfig.RegisterRoutes(RouteTable.Routes);
- UnityConfig.RegisterComponents();
- }
- }
- }
We have added the UnityConfig.RegisterComponents(); line.
Step 25
Open UnityConfig.cs file, which was created at installation time.
Step 26
Paste the below code in UnityConfig.cs file.
- using System.Web.Mvc;
- using Microsoft.Practices.Unity;
- using Unity.Mvc5;
- using DAL;
- using Services;
-
- namespace DI
- {
- public static class UnityConfig
- {
- public static void RegisterComponents()
- {
- var container = new UnityContainer();
-
- DependencyResolver.SetResolver(new UnityDependencyResolver(container));
- container.RegisterType<ICustomerRepository, CustomerRepository>();
- container.RegisterType<ICustomerService, CustomerService>();
- }
- }
- }
Here, we have to mention the mappings, which interface will create which class object.
ICustomerRepository will create a CustomerRepository object and ICustomerService will create a CustomerService object in runtime. So we have mentioned those mappings.
Step 27
Now Right click on Controller folder Goto Add=>Controller…
Step 28
Select MVC 5 Empty Controller, click on Add button
Step 29
If you are getting any dll error, just build the solution once and add the controller.
Name it as “CustomerController”
Step 30
Paste the below code in CustomerController
- using Services;
- using System.Web.Mvc;
-
- namespace DI.Controllers
- {
- public class CustomerController : Controller
- {
- private ICustomerService _iCustomerService;
-
- public CustomerController(ICustomerService iCustomerService)
- {
- _iCustomerService = iCustomerService;
- }
-
- public ActionResult GetCustomers()
- {
- return Json(_iCustomerService.GetCustomers(), JsonRequestBehavior.AllowGet);
- }
- }
- }
Here we are injecting ICustomerService interface variable from constructor of the controller.
Here we didn’t mention any classname, we are just passing interface variable, so at runtime, it will call respective class object using mapping which we have done in previous steps.
- container.RegisterType<ICustomerService, CustomerService>();
Step 31
Now, run the application and see -
http://localhost:63050/customer/GetCustomers
Map theURLl to “customer/GetCustomers” method, will receive the JSON result as below.
Step 32
Now, debug the application and see how it works in background.
_iCustomerService is having Services.CustomerService class object.
Step 33
Press F11 when the control is in return statement.
It will hit the GetCustomers method in CustomerService class.
Again, press F11.
It will hit the DAL layer CustomerRepository class method.
So, in runtime, it is creating respective mapped objects to interface variables.