Hot File

Dependency Inversion Principle and the Dependency Injection Pattern

View: 836    Dowload: 0   Comment: 0   Post by: hanhga  
Author: none   Category: Design Ideas   Fields: Computers - Technology

0 point/2 review File has been tested

Everyday we write lots of code which are tightly coupled and when complexity grows code will eventually deteriorate into Spaghetti Code. Which violates the Dependency inversion principle. In software design, tight coupling is often considered to be a liability in design. When one class knows explicitly about the design and implementation of another class, its raise the risk that changes to one class will break the other class. On the other hand loosely coupled code can stay maintainable and well-designed. The benefits of using loose coupling aren’t always instantly evident, but they become visible over time, as the complexity of a code grows. Dependency Injection Pattern is nothing but the best way to enable loose coupling. In this article I will try to explain how we can use DI in our everyday practice with simple approach without DI containers.

Introduction

Background

 

Uncle Bob "SOLID" object-oriented design principles “D” stands for Dependency Inversion Principle

The Dependency Inversion Principle states:  

  • High level modules should not depend upon low level modules. Both should depend upon abstractions.
  • Abstractions should not depend upon details. Details should depend upon abstractions.

Sometimes its not easy to maintain DIP while writing your code. Practice and experience will help you out from this. The Dependency Inversion principle (DIP) helps to loosely couple your code by ensuring that your high-level modules depend on abstractions rather than concrete implementations of lower-level modules. The Dependency Injection pattern is an application/ implementation of this principle. 

The basic idea of this article is that how we can make our code loosely coupled.

Using the code 

Let's start from the code. Many of us probably seen (or written) code like this: 

public class Email
{
    public void SendEmail()
    {
        // code
    }
}

public class Notification
{
    private Email _email;
    public Notification()
    {
        _email = new Email();
    }

    public void PromotionalNotification()
    {
        _email.SendEmail();
    }
}

Here Notification class has a dependency on Email class. In this case, the notification creates an instance of the e-mail directly inside of the notifications constructor and knows exactly what kind of email class it’s creating and consuming. It's violate DIP.

A class has dependency on some other class and knows a lot about the other classes it interacts with is said to be tightly coupled. When a class knows explicitly about the design and implementation of another class, its raise the risk that changes to one class will break the other class.

What if we want to send some other types of notifications like SMS or save into the DB? To enable this behavior we have to modify the implementation of the notification class.

To reduce dependency we have to do couple of steps. Firstly introduce an abstraction layer between these two classes. We can use interface/ abstract class to represent the abstractions between Notification and Email.

public interface IMessageService
{
    void SendMessage();
}
public class Email : IMessageService
{
    public void SendMessage()
    {
        // code
    }
}
public class Notification
{
    private IMessageService _iMessageService;

    public Notification()
    {
        _iMessageService = new Email();
    }
    public void PromotionalNotification()
    {
        _iMessageService.SendMessage();
    }
}

Here, introduced an interface IMessageService to represent the abstraction, and ensure that the Notification class only calls methods or properties on that interface.

Secondly need to move the creation of the Email class outside of the Notification. We can achieve this by DI pattern.  

DI is the act of supplying all classes that a service needs rather that leaving the responsibility to the service to obtain dependent classes. DI typically comes in three flavors:

  • Constructor Injection
  • Property Injection
  • Method Injection

Using these injections we can achieve the second step. I am applying these injections in our tightly couple code. And making our code loosely couple and maintaining DIP. 

Constructor Injection

This is the most common dependency injection. When a class requires an instance of a DEPENDENCY to work, we can supply that DEPENDENCY through the class’s constructor. Now let’s change the Notification class to support constructor injection:

public class Notification
{
    private IMessageService _iMessageService;

    public Notification(IMessageService _messageService)
    {
        this._iMessageService = _messageService;
    }
    public void PromotionalNotification()
    {
        _iMessageService.SendMessage();
    }
}

In this code, there are several benefits: the implementation of the constructor is very simple, it has reduced the number of things Notification needs to know about, any code that wants to create an instance of Notification can look at the constructor and know exactly what kinds of things are necessary to make Notification function.  So, our code is now loosely coupled and easily maintainable.

Property Injection

Property injection/ setter injection is less common dependency injection, it is best used when dependency is optional. We have to expose a writable property that allows a client to supply a different implementation of the class’s DEPENDENCY than the default. We have to change our Notification class to apply property injection:

public class Notification
{
    public IMessageService MessageService
    {
        get;
        set;
    }
    public void PromotionalNotification()
    {

        if (MessageService == null)
        {
            // some error message
        }
        else
        {
            MessageService.SendMessage();

        }
    }
}

We have removed the constructor and replaced it with a property. Now we are providing dependency via properties rather than the constructor. In the PromotionalNotifications method we have to check that it has already provided the service dependency or not by checking MessageService value.  Here, we able to made our code loosely coupled.

Method Injection 

When a DEPENDENCY can vary with each method call, you can supply it via a method parameter. Suppose our application will send Email also SMS or save notification message into DB. We can use method injection. We can write the code following way:

public class Email : IMessageService
{
    public void SendMessage()
    {
        // code for the mail send
    }
}
public class SMS : IMessageService
{
    public void SendMessage()
    {
        // code for the sms send
    }
}

public class Notification
{
    public void PromotionalNotification(IMessageService _messageService)
    {
        _messageService.SendMessage();
    }
}

Here, IMessageService has implemented in both Email class and SMS class. We can supply different types of MessageService as a parameter to the PromotionalNotification method to perform the notification accordingly.  So, here dependency is varying every method call by different parameters.

In a tightly coupled scenario like the example, we can apply any of these injection to make our code loosely coupled. It's depends on the scenario which injection we will apply. We can apply more than one in a single scenario.

Conclusion 

Surprisingly its very easy to write tightly coupled code! One of the many reason is that while introducing new/ additional features in our code. Every time we use a new keyword we introduce a tight coupling. We can minimize this by introducing constructor injection. In general developers like to use constructor injection over the other two types of injection. But of course we can mix  both of them, while constructor will be mandatory and other two will be optional. Hope this article will help you to begin DI in your every day code.

Dependency Inversion Principle and the Dependency Injection Pattern

Dependency Inversion Principle and the Dependency Injection Pattern Posted on 11-04-2014  Everyday we write lots of code which are tightly coupled and when complexity grows code will eventually deteriorate into Spaghetti Code. Which violates the Dependency inversion principle. In software design, tight coupling is often considered to be a liability in design. When one class knows explicitly about the design and implementation of another class, its raise the risk that changes to one class will break the other class. On the other hand loosely coupled code can stay maintainable and well-designed. The benefits of using loose coupling aren’t always instantly evident, but they become visible over time, as the complexity of a code grows. Dependency Injection Pattern is nothing but the best way to enable loose coupling. In this article I will try to explain how we can use DI in our everyday practice with simple approach without DI containers. 5/10 836

Comment:

To comment you must be logged in members.

Files with category

  • MasterPages reinvented - a Component Based Template Engine for ASP.NET

    View: 1618    Download: 2   Comment: 0   Author: none  

    MasterPages reinvented - a Component Based Template Engine for ASP.NET

    Category: Design Ideas
    Fields: Other

    2.25/2 review
    A template engine allows you to render the contents of your ASP.NET web forms as parts of a Master Page (template). This template engine provides a new approach regarding the separation of ASP.NET templates and web forms. The features at a...

  • A Quick Look at API Design

    View: 1224    Download: 0   Comment: 0   Author: none  

    A Quick Look at API Design

    Category: Design Ideas
    Fields: Other

    0/0 review
    Whether you know it or not, you are an API (Application Programmer Interface) designer. Every time you create a new class or enhance an existing one, the non-private methods and properties create, or add to, an API. So it makes sense, I think, to...

  • User-driven applications

    View: 2168    Download: 0   Comment: 0   Author: none  

    User-driven applications

    Category: Design Ideas
    Fields: Other

    0/4 review
    This is the second article in a series of two. The first article – on the theory of moveable objects – was about the basic algorithm and its use in designing different moveable / resizable objects. Such objects are in high demand in many programming...

  • A Reflective and Translucent Glass Panel

    View: 2710    Download: 3   Comment: 0   Author: none  

    A Reflective and Translucent Glass Panel

    Category: Design Ideas
    Fields: Other

    0/7 review
    This component is the logical suite of the AlphaGradientPanel published here on CodeProject. It replaces the original System.Windows.Form.Panel by a nifty glassy one.

  • Distributed Command Pattern - an extension of command pattern for connected systems

    View: 3586    Download: 4   Comment: 0   Author: none  

    Distributed Command Pattern - an extension of command pattern for connected systems

    Category: Design Ideas
    Fields: Accounting

    0/7 review
    Distributed Command Pattern is a proposed pattern for solving the extra architectural design issues which need to be considered for connected systems than designing regular applications. The goal of this pattern is to “Have the same design for both...

  • Validators for Windows Forms - ValidationProvider Control

    View: 5291    Download: 2   Comment: 0   Author: none  

    Validators for Windows Forms - ValidationProvider Control

    Category: Design Ideas
    Fields: Accounting

    0/8 review
    Do you spend most of your time writing custom validations on Windows Forms? Have you ever wanted an equivalent WinForm validator like in WebForm? Noogen ValidationProvider can help you speed up your WinForms design time by providing powerful, easy...

  • Integrating Help In Your Iron Speed Designer Application

    View: 1599    Download: 0   Comment: 0   Author: none  

    Integrating Help In Your Iron Speed Designer Application

    Category: Design Ideas
    Fields: Computers - Technology

    0/2 review
    This article is in the Product Showcase section for our sponsors at CodeProject. These reviews are intended to provide you with information on products and services that we consider useful and of value to developers.

  • Dependency Inversion Principle and the Dependency Injection Pattern

    View: 836    Download: 0   Comment: 0   Author: none  

    Dependency Inversion Principle and the Dependency Injection Pattern

    Category: Design Ideas
    Fields: Computers - Technology

    0/2 review
    Everyday we write lots of code which are tightly coupled and when complexity grows code will eventually deteriorate into Spaghetti Code. Which violates the Dependency inversion principle. In software design, tight coupling is often considered to be a...

 
Newsletter Email

File suggestion for you

File top downloads

logo codetitle
Codetitle.com - library source code to share, download the file to the community
Copyright © 2015. All rights reserved. codetitle.com Develope by Vinagon .Ltd