Wednesday 9 May 2012

Inversion of Control : Overview and Example


Introduction

Definition: “Inversion of Control, is an abstract principal describing an aspect of some software architecture design in which the flow of control of a system is inverted in comparison to procedural programming.”
Let’s go in simple manner what happened in procedural programming is chunk of code that uses or consumes another chunk of code, is in control of process. It knows what piece of code, which method in which class it uses and in this way it knows about some implementation detail in the code it uses.

Example






Here is a example of such scenario when a class called X uses another class called Y. The consumer class X, needs to consume the class Y, to accomplish something. This is very obvious example, but waits and thinks for a minute, does X really needs to know that it uses Y? Isn’t it enough that X knows that it uses something that has the behavior, the methods, the properties etc. of Y without knowing who actually implement the behavior? By extracting abstract definition of the behavior used by X in Y and let the consumer X to use an instance of that behavior instead of Y. This way X does same thing without knowing the specific about Y










As illustrated above class Y implement interface I and class X uses I. Here interesting matter is though class X still uses Class Y through interface I, but X doesn’t know that it uses Y, it just knows that it uses something that implement I, right now it’s Y but it would be A, B or C that implement interface I. this way we are reducing dependency of X over Y. Now you might have question in your mind, what is dependency? And how it’s dangerous for software?

What is Dependency in terms of classes?

Example mentioned in starting of this article is example of dependent classes. When class X uses any method of class Y or class Y as whole we can says that class X has some level of dependency over class Y. dependency may extend to several levels. i.e. X uses Y, Y uses A and B, A uses C and more. This way this chain go on and on. Problem with this is if we have any change in these classes, it may spawn to multiple classes. Solution of this dependency is define loose relation between classes. One way to achieve this is Inversion of Control pattern. This pattern uses Dependency Injection to eliminate tight coupling between objects. Let’s see dependency with some practical example.

A Sample Scenario
We have a class called LoggerEngine, which is used for logging messages. It had a method called Log which receives a string object as an argument and logs it into file using another class named FileLogger .








The code for LoggerEngine looks like this.















Notice above code, in which Log method creates instance of FileLogger class and then logs the message by using its own Log method. Here you may define all three method to static or there might be singleton instance of FileLogger class. Ways doesn’t matter what is the matter, dependency of LoggerEngine class over FileLogger class. We can solve this matter by creating an abstract definition of the behavior in FileLogger that LoggerEngine needs in the form of interface ILooger and making Log method use an instance of ILogger instead of  an instance of FileLogger












Now LoggerEngine no longer knows about the FileLogger class. It just uses instance of ILogger interface of which FileLogger is one of many possibly implementation. Now in fact we could easily change it so that LoogerEngine logs message on console instead of file without changing single line of code in LoggerEngine.
This all sounds good, but main question is How does LoggerEngine get instance of ILogger? Here we need a way for LoggerEngine to get an instance of ILogger at runtime without knowing about any concrete implementation. There are couple of ways to do that, one of which is through Dependency Injection.

Dependency Injection

This is basic concept for implementing inversion of control (IoC) pattern.
  1. It eliminate tight coupling between objects.
  2. Makes object and application more flexible.
  3. It facilitates to create more loosely coupled objects and their dependencies.

















Constructor Injection

Here object reference would get pass to constructor of business class LoggerEngine. In this case since LoggerEngine class depends on FileLogger class, so reference of FileLogger class will pass steps to implement Constructor Injection.

Step-1 Create an Interface


 Only method of interface will expose in business class.

Step-2 Implement interface to FileLogger class

 















Object of FileLogger class is going to be referenced by LoggerEngine class. So this class needs to be implement interface.

Step-3 Make reference of interface in LoggerEngine class











Step-4 Create a third party class, who creates instance of all this objects. 












Step 5 Use this third party class at client side.



Disadvantage of constructor injection
  • In constructor injection business logic class doesn’t have default constructor.
  • Once the class is instantiated, object dependency cannot be  changed.
Setter Injection

This uses the Properties to inject dependency. Here rather than creating a reference and assign them in constructor, it has been done in properties. By this way LoggingEngine class could have default constructor.

Step-1 Same as Constructor Injection

Step-2 Same as Constructor Injection

Step-3 LoggerEngine.cs












In LoggerEngine class, there is property Logger, which is setting and getting value of reference of interface.

Step-4 There is some changes in third party class















Step-5 Same as Constructor Injection

Advantages of Setter Injection

  • It’s more flexible than Constructor Injection.
  • Dependency of object can be change without creating any instance.
  • Dependency of object can be change without changing constructor.
  • Setters has constructive and self descriptive meaningful name that simplify understanding and using them

Interface Injection

In this instance creation is transferred to an additional interface. This interface passes as an argument in calling method.

Step-1 Same as Constructor Injection

Step-2 Same as Constructor Injection

Step-3 Create an interface and its implemented class, which creates instance.








Here one more interface and its implemented class has defined which are responsible for instance creation.

Step-4 LoggerEngine.cs








Step-5 Our third party class will be















Step-6 Same as Step-5 in Constructor Injection

Service Locator Injection

Here one Service class introduced which contains either static method or Service class may be uses singleton pattern.

Step-1 Same as Constructor Injection

Step-2 Same as Constructor Injection

Step-3 Define service class as follow






Here we have static writeonly property Logger which is uses for setting value of reference of ILogger instance and a static mettod which is uses for getting value of reference of ILogger instance

Step-4 LoggerEngine.cs







Step-5 IoCClass.cs

















Step-6 Same as Step-5 in Constructor Injection

Generic-Type Injectiom

In this method either we can define Generic LoggerEngine class or Generic method in LoggerEngine clas. Generic method would be more appropriate because if we use Generic class then it will cause same problems which are identified in Constructor Injection.

Step-1 Same as Constructor Injection

Step-2 Same as Constructor Injection

Step-3
 
Let’s define LoggerEngine class which contains generic method for writing log






Here we explicitly mentioned that our TLogger would be any reference implementation of ILogger.

Step-4

Our third party code would be as per shown below.
















Step-5 Same as in Constructor Injection

Benefits of Inversion of Controls
  • We can reduce dependency between objects and can design more flexible systems.
  • We can isolate our code at a time of unit testing.