Sunday, July 11, 2010

Inversion of Control (IOC) in .Net / Dependency Injection in .Net

As always with design patterns let me start the Inversion of Control and dependency injection concepts with a non-software example.

Non-software example


You work in a small sales organization where you need to travel a lot. Your company has a set of preferred agencies for booking flight and cab. Generally while travelling you arrange for flight tickets by calling the travel agency and also arrange cab by calling the cab agency. Now suddenly your organization decided to change the preferred vendors for both flight and cab reservation. So next time you travel you need to get the new preferred vendor details and book the tickets. So here there is a tight coupling between you and the preferred vendors. So when there is a change in the preferred vendors you also need to change accordingly.


What could have been better to remove this dependency, I mean how we could have made it loosely coupled?


Assume that your organization has an admin department, where for every booking you need to reach them. So while traveling every time you reach the admin department without bothering where and how they book the flight and cab for you. As your organization changed the preferred vendor you do not need to worry about, you still get the same service from your admin department. So there is loose coupling between you and the travel agencies. Change of preferred vendors does not have an impact on you.

In short this is what Inversion of Control (IOC) is in real life. Instead of you worrying about booking the tickets, keeping track of changing vendors someone else (admin department) is going to do everything and give it to you for use. In other words you are inverting the control of booking the tickets to someone else. The below example shall give us a better understanding of IOC and DI.

Software Example of Inversion of Control and Dependency Injection


John is a software architect for the sales portal of the fortune 500 organizations. There is a need from business to create a new module to capture all potential customers along with their demographic details (details like address, city etc) in the sales portal. John was given the responsibility to design this module.

John’s Design approach


John decided to have this module in two different classes. One class where he would keep the potential customers and the other class to hold the demographic details. Below is how both the classes and implementation would look like.


PotentialCustomers Class


public class PotentialCustomers
{
private Address _objAddress;


public PotentialCustomers(Address objAddr)
{
_objAddress = new Address();
//set all address properties based on some business rules
}
public int AddPotentialCustomer()
{
//Take the _objAdress and pass all the variales to the backend
return 0;
}
}


Address Class


public class Address
{
public string address1 { get; set; }
public string address2 { get; set; }
public string city { get; set; }
public string country { get; set; }
}


Hmmm.. okay. This solution has issues but John did not realize until the day when business asked John to capture additional demographic details like phone and email address.

Opps… John suddenly realized the following issues with his design.

i. The Potential Customer class controls the creation Address object. Also the address object is directly referenced in the Potential Customer class which leads to tight coupling between these two classes.
ii. Also any changes to address class will lead to change of Potential Customer class.
Now John realized that the issue with this design is the creation of address object in the Potential Customer class. The solution is also lies in shifting the object creation process to something else. In other words inverting this object creation process to something else. This inversion process is nothing but Inversion of Control (IOC).

Principle of IOC

• Main classes aggregating other classes should not depend on the direct implementation of the aggregated classes. Both the classes should depend on abstraction. So the customer class should not depend directly on the address class. Both address and customer class should depend on an abstraction either using interface or abstract class.
• Abstraction should not depend on details, details should depend on abstraction.

So in John’s approach it is like the address class telling the PotentialCustomer class that do not create me, I will create myself using someone else.

What is Dependency Injection?


Okay, now with this approach of John we know what IOC is, then what Dependency Injection is. Well the way we achieve IOC is Dependency injection. Instead of creating and using the address object in the Potential Customer class we are going to inject the address class to the Potential Customer class. By injecting the Address class to the Potential Customer class we remove the tight coupling between the Address and Potential Customer class and invert the address object creation process to someone else. IOC can be achieved by any of the below Dependency Injection process.

• Constructor way
• Exposing getter and setter
• Interface implementation
• Service locator

Let us see how to achieve these.

Constructor Way
In this method of Dependency Injection we pass the object reference in the constructor itself. So when the client creates the object it passes the object in the constructor itself. This is how the code is going to look like
public class PotentialCustomers
{
private IAddress _objAddress;


public PotentialCustomers(IAddress objAddr)
{
_objAddress = objAddr;
}
public int AddPotentialCustomer()
{
//Take the _objAdress and pass all the variales to the backend
return 0;
}
}


Note that we are not referring the Address class here rather we are referring IAddress Interface. The drawback with this method is that, it is not suitable for clients who have only one constructor.

Exposing Getter and Setter


This is the easiest way of Dependency Injection and is widely used. The dependent objects are exposed through properties. With getter and setter the Potential Customer class would look like below.

public class PotentialCustomers
{
public IAddress Address {get;set;}
}


Interface Implementation


With interface implementation the code would look like below. The code is pretty straight forward.

public class PotentialCustomers:IDIInjection
{
public void setAddress(IAddress objAddr)
{
//Implementation
}
}
public interface IDIInjection
{
public void setAddress(IAddress objAddr);
}


Service Locator


The other way to inject dependency is by using service locator. Your main class which will aggregate the child object will use the service locator to obtain instance of the address object. The service locator class does not create instances of the address object, it provides a methodology to register and find the services which will help in creating objects.


public class PotentialCustomers
{
public IAddress _objAddress;


public PotentialCustomers()
{
_objAddress = LocateAddress.getAddress()
}
}
public static class LocateAddress
{
public static IAddress getAddress()
{
return null;
}
}


Hope this helps…

Actual implementation of Dependency Injections can be done easily by using containers like Windsor; however this is not in scope of this article.

References:
http://www.theserverside.com/news/1321158/A-beginners-guide-to-Dependency-Injection
http://www.codeproject.com/KB/aspnet/IOCDI.aspx

Tuesday, July 6, 2010

UrlReferrer property in ASP.Net

For a scenario where you want to reload the previous page on click event of the Back Button of New redirected page, the following solution will be helpful.

Sol:- You need to use UrlReferrer property of Request object to access the previous page URL.

Code:-
In the code behind file of the New Page.

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) //check if the webpage is loaded for the first time.
{
ViewState["PreviousPage"] =
Request.UrlReferrer;//Saves the Previous page url in ViewState
}
}

protected void btnBack_Click(object sender, EventArgs e)
{
if (ViewState["PreviousPage"] != null) //Check if the ViewState
//contains Previous page URL
{
Response.Redirect(ViewState["PreviousPage"].ToString());//Redirect to
//Previous page by retrieving the PreviousPage Url from ViewState.
}
}

Monday, July 5, 2010

?? operator in C#

The ?? operator returns the left-hand operand if it is not null, or else it returns the right operand. For example:

int? x = null;
...
// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;
The ?? operator also works with reference types:

//message = param, unless param is null
//in which case message = "No message"
string message = param ?? "No message";