Home > Patterns and Practices > Inversion of Control, Dependency Inversion Principle and Dependency Injection

Inversion of Control, Dependency Inversion Principle and Dependency Injection

Inaroozhthum naara malaranaiyar katrathu
unara virithu urayaathaar – Valluvar
Meaning: One is like a flower which doesn’t have fragrance if (s)he cannot explain in detail what (s)he has read.
This is exactly how I was feeling in the last couple of discussions we had on Inversion of Control(IoC).

Here’s an attempt.
A program is in control, a program calls a library.
A framework is in control, A framework calls a program.
This is called Inversion of Control (other words Hollywood Principle, Don’t call us we’ll call you)
Why should the framework call you? We’ll just step a few years back in history when people were programming against the Win32 API.

Then

#include <windows.h>
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
        MSG Msg;
        HWND hWnd;
        WNDCLASSEX WndClsEx;
        // Create the application window
        WndClsEx.cbSize = sizeof(WNDCLASSEX);
        WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
        WndClsEx.lpfnWndProc = WndProcedure;
        WndClsEx.cbClsExtra = 0;
        WndClsEx.cbWndExtra = 0;
        WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
        WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        WndClsEx.lpszMenuName = NULL;
        WndClsEx.lpszClassName = ClsName;
        WndClsEx.hInstance = hInstance;
        WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
        // Register the application
        RegisterClassEx(&WndClsEx);
        // Create the window object
        hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
        // Find out if the window was created
        if( !hWnd ) // If the window was not created,
                return 0; // stop the application
        // Display the window to the user
        ShowWindow(hWnd, SW_SHOWNORMAL);
        UpdateWindow(hWnd);
        // Decode and treat the messages
        // as long as the application is running
        while( GetMessage(&Msg, NULL, 0, 0) )
        {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
        }
        return Msg.wParam;
}
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{
// If the user wants to close the application
case WM_DESTROY:
// then close it
PostQuitMessage(WM_QUIT);
break;
default:
// Process the left-over messages
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
// If something was not done, let it go
return 0;
}
Almost every program written then used to have these code in addition to the application code. So a Framework can have this code built in and we can provide the application specific code which the framework can call. By that way the Framework can have all the plumbing and leave the application only with things which the application is interested in.

Now

using System;
using System.Windows.Forms;
public class BasicApp : Form {
public static void Main(string args[])  {
BasicApp form = new BasicApp();
Application.Run(form);
}
public BasicApp() {
this.OnLoad += new EventHandler(HandleLoad);
}
public void HandleLoad(object sender, EventArgs e) {
MessageBox.Show("Hello World!");
}
}

Inversion of Control takes reuse to the next level. This code has very less plumbing compared to the Win32 one. The framework calls you (as opposed to you calling the Win32 API) using the delegate.

How can frameworks call your code?
The problem in Framework calling your code is that the Framework does not and cannot know that your code exists. So How can it depend on you code and call you. Welcome to Depdency Inversion Principle (DIP). Both the framework and your code depdend on a abstraction and the abstraction provides the famework the ability to call you. Rather the the Higher level module (the framework) depdening on the lower level module (your code). Both depend on the abstraction (delegate). What are the possible abstractions that can be used?

The framework can use
Abstract classes (virtual dispatch)
Interfaces
Delegates
Function Pointers
Closures
Special Methods (e.g. Main)

What is Dependency Injection?
When an object is dependent on another object, the dependency can created by the object itself (the object is in control). Or an external framework can instantiate and provide the depedency (typically based on configuration, making your code more pluggable. The framework is in control here). This is called Depdency Injection. This is a specific case of IoC. DI combined with DIP can make you code more pluggable.

Suggested Reading:
Inversion of Control:http://martinfowler.com/bliki/InversionOfControl.html
Dependency Inversion Principle: http://www.objectmentor.com/resources/articles/dip.pdf
Dependency Injection: http://www.martinfowler.com/articles/injection.html
The Delegates Abstraction: http://sendhil.spaces.live.com/blog/cns!30862CF919BD131A!346.entry
Closures: http://www.martinfowler.com/bliki/Closure.html

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: