Dependency Injection using Unity

 

Thank you everyone for your valuable feedback and awesome response on my last post on Repository Pattern. In this post we will see what is Dependency Injection and how to implement it, we will try to use some of the frameworks available to achieve the same.

INTRODUCTION:

Dependency Injection is a design pattern, which implements Inversion Of Control(IoC) for resolving dependency. So what it means, it helps us in implementing loose coupling between our objects. The terms tightly coupled and loosely coupled, is used many times while working in our application. Let’s see what these 2 terms means

Tightly Coupled System: We are always advised to create a system which is not tightly coupled, a tightly coupled system is where all objects are tightly coupled to each other, if you want to remove  one sub-Systems from our application, it will require many changes across the application, and sometime writing almost entire code again.If you have used logging system in any application like log4Net, we always write code in our client code where we want to log something, just imagine if tomorrow we want to replace the logging with DB logger. We need to replace all code, just think about the time wasted in such a boring task, replacing an object in all classes, i am sure no one wants to do that.

Loosely Coupled System: The answer to avoid the above issue is creating loosely coupled system, where we are easily able to replace an similar object easily.

Now we are aware of what we want to achieve, let’s go ahead and implement Di using unity framework and MVC. There are many DI containers available, we will cover most of them in future posts.

PREREQUISITE:

We will be using be using below given IDE and Frameworks in this blog.

  1. VS 2015
  2. Entity Framework 6.0
  3. MVC controller
  4. Class Library Project

We will create a WebApi project and consume the Repository layer directly in our API controllers to see it working, in real life project please have a service layer in between. So let’s get’s started and create our project.

  1. Create a project Go to File->New->Project name it as StudentApp and click OK. Choose ASP.NET Web Application.Project.JPG
  2. On Next page create MVC from templates, an select Web API from “Add folders and core references for”, MVC will be select by default, click OK to wait for some time, your project will be loaded.Template.JPG
  3. Now once our project is loaded, let’s see what are the thing we need to make it work, as informed we will create a different project to create our Repository Layer.
  4. Leave your project as it is and a new project , right click on solution and Add->New Project and choose Class Library, name it as StudentApp.Repository and click ok.
  5. Let’s add Entity Framework as reference to our poject, we will use NuGet so right click on this recently created project and click Manage NuGet Packages and goto Browse tab and search for EntityFramework and install, it will ask to accept, click accept and references will be added.
  6. In Entity Framework we create conext classes which connects to your database, there are 2 options, we can use a single context class and all Models or We can create a each context for every Models availabe.
  7. For database we will be using localDb, if you open your web.config file from studentApp, we will find a DefaultConnection as connectionString, we will change the database name and change it to StudentDataBase.
  8. Now we need one more project for our Models, let’s add a new ClassLibrary project and name it as StudentApp.ModelModels.JPG
  9. Project will be loaded with Class1.cs , let’s rename the class and change it to Student, it will ask whether, you want to rename all references say yes.
  10. Now add few properties to our class, we will see the advantages of entity framework as well. 
    namespace StudentApp.Model
    {
        public class Student
        {
            public int StudentID { get; set; }
            public string FristName { get; set; }
            public string LastName { get; set; }
            public DateTime DateOfBirth { get; set; }
            public DateTime CreatedDate { get; set; }
            public DateTime? ModeifiedDate { get; set; }
        }
    }
    
    
  11. Done with our model class, now build our model project and add reference of this project to our Repository. To add just right click on our Repository project Add-> reference, a box will open from left side choose Project. It will show us 2 option choose StdentApp.Model and click OK.reference
  12. In our Repository project rename the class1.cs file to StudentContext.cs. So if you are thinking what context class does, it is the model which will talk to our database and help us retrieve the data from DB, let DB know which are the table DB needs to create, with which properties and which database to target.
  13. To create out StudentContext we need to inherit DbContext class, our default constructor will have parameter which will be connectionString Name from our config class. Let’s see the code below.
    using StudentApp.Model;
    using System.Data.Entity;
    
    namespace StudentApp.Repository
    {
        public class StudentContext : DbContext
        {
            public StudentContext() : base("DefaultConnection")
            {
    
            }
    
            public  DbSet<Student> Student { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
            }
        }
    }
    
  14. Line number 5 has the default constructor which will initialize our database, the parameter passed is same as our connectionString Name.
  15. Line number 10 has the property as Student, DbSet<> tell the database that we need to create a table with name as Student in our database. and onModelCreting() method let’s us modify properties to table before table is created in DB.
  16. As already informed in introduction, repository pattern creates an abstraction between Service and data access layer, it means there will be interface or abstract class is involved.
  17. Let’s create an folder as Interface,  we will add all interface in this folder. So let’s add our interface called IStudentRepository and 2 methods as “Get” and “Add”. 
    using StudentApp.Model;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace StudentApp.Repository.Interface
    {
        public interface IStudentRepository
        {
             Task<List<Student>> Get();
             Task<bool> Add(Student student);
        }
    }
    
  18. Now we need to implement the interface as well, let’s add a class called StudentRepository and implement the IStudentRepository 
    using StudentApp.Model;
    using StudentApp.Repository.Interface;
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Threading.Tasks;
    
    namespace StudentApp.Repository
    {
        public class StudentRepository : IStudentRepository
        {
            private StudentContext _context = new StudentContext();
    
            public StudentRepository(StudentContext context)
            {
                this._context = context;
            }
    
            public async Task<List<Student>> Get()
            {
                return await _context.Student.ToListAsync();
            }
    
            public async Task<bool> Add(Student student)
            {
                student.CreatedDate = DateTime.Now;
                _context.Student.Add(student);
                int x = await _context.SaveChangesAsync();
                return x == 0 ? false : true;
            }
        }
    }
    
  19. If you notice line number 14 , we are passing StudentContext as  parameter in StudentRepository class, this is called Construction injection.
  20. As discussed in previous blog, in real world project its always good to have service layer between your controller and Repository. So let’s go ahead and add a service layer as well.
  21. Right click on solution and add new project name it as StudentApp.Service, rename the class1.cs as StudentService, also add a new folder Interface and add a new interface IStudentService into that folder.
  22. we will add same 2 methods Get And Add in our interface 
    using StudentApp.Model;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace StudentApp.Service.Interface
    {
        public interface IStudentService
        {
            Task<List<Student>> Get();
            Task<bool> Add(Student student);
    
        }
    }
    
    .
  23. Now let’s inherit this interface into our StudentService, we will call our repository from this layer rather than from controller, we will have one more level of abstraction between our UI and Repository.
  24. To access repository we need to add create some instance into this class right, lets go ahead and create a instance
    using StudentApp.Model;
    using StudentApp.Repository.Interface;
    using StudentApp.Service.Interface;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace StudentApp.Service
    {
        public class StudentService : IStudentService
        {
            private IStudentRepository __repo;
            public StudentService(IStudentRepository repo)
            {
    
                this.__repo = repo;
            }
    
            public async Task<bool> Add(Student student)
            {
                return await __repo.Add(student);
            }
    
            public async Task<List<Student>> Get()
            {
                return await __repo.Get();
            }
        }
    }
    
    .
  25. If you notice the constructor StudentService it has IStudentRepository as parameter, which is called constructor injection, as we saw above with studentContext, but we are not creating any instance of StudentRepository class, isn’t it strange as we are aware we need to create the instance of class,interface only holds the definition of methods, this is beauty of DI.
  26. If you compile this project now it will be compiled, but it will throw an error if you try to call any method, let’s see how to resolve the dependency using Unity.
  27. Now in our StudentApp project add reference and choose StudentApp.Service and StudentApp.Model.
  28. Now let’s move ahead and add a new controller called as StudentController, to add Right click on Controller folder and Add-> Controller select MVC5 controller – Empty and name it as StudentController.
  29. We will have 2 Actions as Get and Post 
    using StudentApp.Model;
    using StudentApp.Service.Interface;
    using System.Threading.Tasks;
    using System.Web.Mvc;
    
    namespace StudentApp.Controllers
    {
        public class StudentController : Controller
        {
            private IStudentService _service;      
            public StudentController(IStudentService service)
            {
                this._service = service;
            }
    
            [HttpGet]
            public async Task<JsonResult> Get()
            {
                return Json(await _service.Get(), JsonRequestBehavior.AllowGet);
            }
    
            [HttpPost]
            public async Task<bool> Post(Student student)
            {
                return await _service.Add(student);
            }
        }
    }
    
    .Similar to our service we have a constructor injection we are injecting the IStudentService, here also we are not creating instance of StudentService, if you compile this solution now it will be built, but will throw the exception if you try to call any action.
  30. Now let’s go ahead and add Unity for MVC, right click on StudentApp project and select Manage Nuget Packages, go to Browse tab and search for Unity select Unity.MVC and click install.Nuget
  31. Once this is installed,this will add 2 files UnityConfig.cs and UnityMvcActivator.cs class, you can find both the classes in App_Start folder.
  32. We only need to make changes into UnityConfig.cs file, so open the same and find the RegisterTypes method. If you notice  there are some comments, there  are 2 options to configure DI(Dependency Injection) either using web.cofig fileor using code. We will see second option using code.
  33. You will find // TODO: Register your types here
    // container.RegisterType<IProductRepository, ProductRepository>();  just below that add we will configure our classes  
    using Microsoft.Practices.Unity;
    using StudentApp.Repository;
    using StudentApp.Repository.Interface;
    using StudentApp.Service;
    using StudentApp.Service.Interface;
    using System;
    
    namespace StudentApp.App_Start
    {
        /// <summary>
        /// Specifies the Unity configuration for the main container.
        /// </summary>
        public class UnityConfig
        {
            #region Unity Container
            private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
            {
                var container = new UnityContainer();
                RegisterTypes(container);
                return container;
            });
    
            /// <summary>
            /// Gets the configured Unity container.
            /// </summary>
            public static IUnityContainer GetConfiguredContainer()
            {
                return container.Value;
            }
            #endregion
    
            /// <summary>Registers the type mappings with the Unity container.</summary>
            /// <param name="container">The unity container to configure.</param>
            /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
            /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
            public static void RegisterTypes(IUnityContainer container)
            {
                // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
                // container.LoadConfiguration();
    
                // TODO: Register your types here
                // container.RegisterType<IProductRepository, ProductRepository>();
                container.RegisterType<IStudentService,StudentService>();
                container.RegisterType<IStudentRepository, StudentRepository>();
            }
        }
    }
    
  34. Notice line no.43 and 44.
  35. Now let’s press F5 and see the result.DIAdd
  36. Let’s see the same result for Get                                           Request1Response
  37. We can achieve the same using config file.
    <configSections>
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
    </configSections>
    <unity>
      <container>
        <register type="StudentApp.Service.Interface.IStudentService, Services" mapTo="StudentApp.Service.StudentService, Services" />
        <register type="StudentApp.Repository.Interface.IStudentRepository, Services" mapTo="StudentApp.Repository.StudentRepository, Services" />
      </container>
    </unity>
    .
  38. If we add a debugger on StudentController constructor, and go to immediate window, and write this._service, we will get {StudentApp.Service.StudentService}
    __repo: {StudentApp.Repository.StudentRepository}, here we are getting the actual objects.

 

CONCLUSION:

So what did we achieved here, it gives the solution to our actual problem discussed isn’t it.

There are several advantages as well, which you might have noticed if you are still creating the class object and using it.Below are few of them

  1. Reduces class coupling
  2. Code reuse

There are several other containers available as well.

  1. spring.Net
  2. StructureMap
  3. Ninject

and many others, just keep one thing in mind, if you want to choose one of them, choose any one which you like.

You can get the code below:

https://github.com/santoshyadav198613/EntityFramework/tree/UnityMVC

Thanks for reading this post, you can mail me on santosh.yadav198613@gmail.com, in case of any question. You can follow my Facebook page as well here.

You can follow me on twitter as @santosh007india.

 

18 Comments


  1. Nice article.
    But I have a quest.
    If the Istudentservice interface is implemented by more than one class. And we need to use the interface for that class then how we use the unity to give the reference of that class.

    Reply

    1. In real world application never use that approach, this is basically service based approach where each interface is implemented by only 1 class.

      Reply

  2. Where from DbCOntext came from and when did StudentApp.Repository changed to StudentApp.DAL

    Reply

    1. Hey Rohit, Thanks for pointing that out, actually by mistake i had used another code snippet, now it is rectified.

      Regards,
      Santosh

      Reply

      1. You can download code from Git, it has the latest code.

        Regards,
        Santosh

        Reply

    2. DbContext is for entity framework.

      Regards,
      Santosh

      Reply

  3. Where to create the folder of interfaces

    Reply

    1. For repository create in Repository project and for Service create in Service project.

      Regards,
      Santosh

      Reply

      1. yes I did it all, but I could not see the last window as an output after running the project. Instead an ASP.NET page opened. Also, could you please send me some MVC projects so that I could practice.

        Reply

        1. Check the URL, I was calling the actions, in chrome add advanced rest client so you will get a tool similar to shown in article.

          Reply

  4. Nice article.

    I can understand the reason for having one more abstraction – service layer, this will be useful when would like to expose only certain methods from repository, otherwise this will be an overhead and more code to maintain. Please correct me if i am wrong.

    Lets say i prefer to use one level of abstraction only i.e. i have repository and the controller will use this repository. Is there a way i could DI the “db context”, rather than creating the context every time on each repository.

    Reply

    1. You can still use DI with your repository. I have added service layer as in real world application, we should try to avoid DB call from our controller.

      Reply

  5. I want to begin my own blog: are there such thing as blogs that are totally “open”, and anybody can notice it? I maintain coming to the type where you have to add other “friends” to use the site.. Links appreciated. Thanks!.

    Reply

    1. You can start writing on LinkedIn, codeproject.

      Reply

  6. Howdy! Ι coupd ɦave sworn ӏ’ѵе visited tis web site before Ьut after lookіng aat
    a few of thᥱ articles I realized іt’s neա tto mе.

    Nonetheless, I’m ɗefinitely delighted І cɑmᥱ acdross it and
    I’ll be book-marking iit ɑnd checdking back often!

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *