Sunday, 11 September 2016

Dependency Injection

Dependency Injection

Dependency Injection, phew! This is not going to be easy. It's huge chapter and takes a lot of napping to complete. Any way let's not beat around the bush. Here is an effort from me to explain what's been explained a thousand times over the net. Let me keep it close to actual usage rather than explaining with basic classes where at the end you would realize you understood the concept but nowhere near to how it would apply to real application. Let's hope people don't doze off with this article. Let's do it.
A part of code perfection would mean on how loosely the layers are coupled which in other word is coined decoupling. An example of decoupling would be. Your web application data layer use Oracle as database. And later on you realize client would to keep the database in Sql Server. Your code should be as such that it doesn't affect the application as a whole. It should be properly decoupled so that a new data layer can be introduced. Decoupling are done with interface. When you have a huge number of layers with lots and lots of classes you would probably miss to define a few dependency. Here the DI come into place as a life saver. DI will figure out who is dependent on whom on it's on. Hope I am not a victim on foot in mouth here. Comments improvement on the same is highly appreciated.
This DI is widely used with MVC. Other framework could probably be using it widely, could be. Why MVC? What's the fuzz about MVC? To me, if we are looking into an SEO friendly, E-commerce website with additional custom development which .NET is already known for. MVC might be the right place we are looking for.
 Let's look into some definition and example which I have collected across books.

 Why ASP.NET MVC?

 1) Soc( Separation of concerns) - From a development point of view MVC promotes great design, cleaner code as compare to normal asp.net web development. It's clean and organized. 
 2) Client side tools are easier to integrate
 3) SEO friendly - Which I believe to be the best positive factor from client point of view. You will find pages like (mybooks.com/science/class 4) which easily defines science book of class five.
4) Gets rid of session collision as since MVC is stateless. It's developer nightmare where in different session are created over different browser or different system for a single user.
5) TDD( test driven development): creating website test are more easier as compared to ASP.net web form.
The disadvantage is rather from a development point of view and not from user perspective. They (psychic developer) called it RAD (Rapid action development). Which practically mean developer need to digest for some time to look into what's cooking in the code. Where as in normal web development a newbie could jump into the code and kick start programming right away. Hope this doesn't confuse reader.

What's Dependency?

Common dependency include
1)      Application layer
a.       Data Access layer & Database
b.      Business layer
2)      External Service & Components
a.       Web services
b.      Third party components
3)      .NET Framework components
a.       File Objects( file.delete(), file.directoryexist())
b.      Web Objects (http context, session, request etc )



A high level dependency chain is as





Dependencies create the following problem

1)      Code is tightly coupled
2)      Difficult to isolate when testing
3)      Difficult to maintain – changing a component is tough as you might know what could other element be effected. If test are in place it could be easily be handled.

Dependency injection

Dependency injection is a software design pattern that implements inversion of control for resolving dependencies. A dependency is an object that can be used (a service). An injection is the passing of a dependency to a dependent object (a client) that would use it. The service is made part of the client's state.[1] Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern. (wikipedia)

Type of dependency injection

1)      Constructor (most widely used)
2)      Setter
3)      Method
As every software has its Pros and Cones, DI has its too

Cones:

1) Dependency injection can make code difficult to trace
2) Some newbie find it difficult to understand

Pros:

1) Decoupling
2) Increases code reusing
3) Improves application testing
4) Improves code maintainability
5) Separated components cleanly

Code Understanding

Let's create a simple web application and name it "SchoolWebApplication". Then create a folder "Models". Create a class file 'Student.cs' in the folder. This class detailed the property of the student class.
namespace SchoolWebApplication
{
    public class Student
    {
        public int RollNumber { get; set; }
        public int Class { get; set; }
        public string FirstName { get; set; }
        public string LastName{ get; set; }
        public string Address { get; set; }
    }
}

Then create the class 'StudentRepository' which comprises of CRUD(create/Read/Update/Delete) methods as per your requirement. As of now we are considering three methods 'getbyRollNumber', 'getAllStudent' and 'insertStudent'. What the method will do is clearly explained by the name convention, I hope. Find the code as below:
namespace SchoolWebApplication
{
    public class StudentRepository:IStudentRepository
    {
        public Student getByRollNumber(int rollnumber)
        {
            Student student = getAllStudent().Where(a => a.RollNumber == rollnumber).FirstOrDefault();
            return student;
        }
        public List<Student> getAllStudent()
        {
            List<Student> students = new List<Student>() {
                new Student() { RollNumber=1,Class=1,FirstName="Raju",LastName="Mighty",Address="Dholakpur" },
                new Student() { RollNumber=2,Class=1,FirstName="Ricky",LastName="Rich",Address="UK" }
            };

            return students;
        }

        public void insertStudent(Student student)
        {
            List<Student> students = getAllStudent();
            students.Add(student);
         }

    }
}

Tight-coupled class

Let's then use the class and bind the data into a grid. Create a web page and name it as "HomeWithCoupledCode.aspx".
   <div>
    <asp:GridView runat="server" ID="gvData" AutoGenerateColumns="true"></asp:GridView>
    </div>

                namespace SchoolWebApplication
{
    public partial class HomeWithCoupling : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            StudentRepository studentRepository = new StudentRepository();
            gvData.DataSource = studentRepository.getAllStudent();
            gvData.DataBind();
         }
    }
}
Wherever you find this "new" instantiation, it would mean it's tightly coupled. It's been a nightmare when you run a test for the code. It would mean inserting data into the application. For a small application it won't make a difference. But imagine you have integrated payment gateway and email configured. This would mean real payment and real mail sending. To solve this nightmare Interface is implemented. And again to make the process more simple dependency injection like autofac is introduced.  

Interface

By the introduction of Interface tight couple is now removed. Class can now call the interface rather than calling the "StudentRepository" class. And hence testing no longer depends on the live service. Below is how the Interface would look like.
namespace SchoolWebApplication
{
   public interface IStudentRepository
    {
        Student getByRollNumber(int rollnumber);
        List<Student> getAllStudent();
        void insertStudent(Student student); 
    }
}

Here is the code where you can call the interface to bind the grid. Please note that "Autofac" reference can then be added using Nuget. Dependency Injection or in short DI provides containers. Interface need to register along with its associated class using the DI container.                  DI container will resolve any property or instance associates with the class.  
<div>
        <asp:Label runat="server" ID="df"></asp:Label>
        <asp:GridView runat="server" ID="ASPxGridView1"></asp:GridView>
       
    </div>
Home.cs
using Autofac;
namespace SchoolWebApplication
{
    public partial class Home : System.Web.UI.Page
    {
        public IStudentRepository _StudentRepository { get; set; }
      
         protected void Page_Load(object sender, EventArgs e)
        {
            IContainer container = Context.Application["Container"] as IContainer;
            container.InjectProperties(this);
            ASPxGridView1.DataSource= _StudentRepository.getAllStudent();
            ASPxGridView1.DataBind();
        }
    }
}

Global.asax 

protected void Application_Start(object sender, EventArgs e)
        {
            ContainerBuilder builder = new ContainerBuilder();

            builder.RegisterType<StudentRepository>().As<IStudentRepository>();
            builder.RegisterType<Home>();

            Application["Container"] = builder.Build();
        }

 I am sure people will be scratching their head and trying to digest on earth was that. But that's what codes are meant to be. I also knew there are points to clear out in this current article. Will enhance this as soon as I step foot on certain understanding.
Also hoping to pen another article on Design Patter.



No comments:

Post a Comment