Click here to Skip to main content
15,880,405 members
Articles / Programming Languages / XML

Dependency Injection in .NET

Rate me:
Please Sign up or sign in to vote.
4.29/5 (6 votes)
25 Feb 2010CPOL2 min read 29.2K   8   3
I'm really on an architecture kick at this point. Honestly, it's probably about time. I find few senior-style job postings that do not ask for some knowledge of Spring.NET or Castle Windsor. Now that I've done a little reading up on the subject, I see that this is for good reason.

I'm really on an architecture kick at this point. Honestly, it's probably about time. I find few senior-style job postings that do not ask for some knowledge of Spring.NET or Castle Windsor. Now that I've done a little reading up on the subject, I see that this is for good reason.

Introduction: What is Dependency Injection?

This stuff is tricky--I'm not going to lie. First of all, I would recommend reading up on the basics. Until you start to really see the power behind defining interfaces and working with abstractions, dependency injection will be unnecessary for you.

Dependency Injection strives to decouple classes from dependencies. For instance:

C#
public interface IComplaintHearer
{
void RegisterComplaint(string message);
}
public class Manager : IComplaintHearer
{
public Manager() { }
public void RegisterComplaint(string message)
{
//do something with message
}
}
public class Employee
{
//completely dependent upon this exact class
private Manager _itsManager;
public Employee() { }
public void Complain(string complaint)
{
_itsManager.RegisterComplaint(complaint);
}
}

What's the issue? What if we want the employee to report to someone other than its immediate boss? Or, what if we want the employee to complain to a co-worker? We would have to completely change the class. Right now this code completely violates the open closed principle (among others) we discussed when reviewing the S.O.L.I.D. principles. So let's use the dependency inversion principle and make this class dependent upon an abstraction:

C#
public interface IComplaintHearer
{
void RegisterComplaint(string message);
}
public class Manager : IComplaintHearer
{
public Manager() { }
public void RegisterComplaint(string message)
{
//do something with message
}
}
public class Employee:IComplaintHearer
{
//completely dependent upon this exact class
private IComplaintHearer _complaintHearer;
public Employee(IComplaintHearer hearer)
{
_complaintHearer=hearer;
}
public void RegisterComplaint(string message)
{
//do something with the message
}
public void Complain(string complaint)
{
_complaintHearer.RegisterComplaint(complaint);
}
}

And we would need to run this code like so:

C#
//we could pass a manager, or another employee if we wanted to
Employee myEmp = new Employee(new Manager());

Injecting the Class, Instead of Providing It

Imagine a scenario where we had tons of classes that implemented the IComplaintHearer interface. We'd have to recompile the code everytime we want to change who the employee complains to. This is where a dependency injection steps in and allows you to:

  1. Specify a class's dependency at run-time
  2. Dynamically use classes in another assembly
  3. Make changes without recompilation

Let's take a look at an example:

C#
public interface IComplaintHearer
{
void RegisterComplaint(string message);
}
public class Manager : IComplaintHearer
{
public Manager() { }
public void RegisterComplaint(string message)
{
//do something with message
}
}
public class Employee:IComplaintHearer
{
//completely dependent upon this exact class
private IComplaintHearer _complaintHearer;

//use the IComplaintHearer subclass that the Dependency Injection Framework 
//(StructureMap in this case) tells us to
// this depends upon the xml that defines what to use (below)
public Employee(): this ( ObjectFactory.GetInstance<icomplainthearer>()){}
public Employee(IComplaintHearer hearer)
{
_complaintHearer=hearer;
}
public void RegisterComplaint(string message)
{
//do something with the message
}
public void Complain(string complaint)
{
_complaintHearer.RegisterComplaint(complaint);
}
}
XML
<structuremap>
<defaultinstance pluggedtype="Example.Manager, Example" 
	plugintype="Example.IComplaintHearer, Example">
</defaultinstance></structuremap>

What just happened? By using the StructureMap Framework for .NET, we just specified the IComplaintHearer that our employee class will default to--the manager. In the XML above, we mapped the expected type/assembly to the default type/assembly. Further, we could set up defaults for all of our classes that we could change later without ever having to change any code. In some ways, I feel like this is moving a problem from one environment to another, but in other ways, I think it is a great architectural tool.

What do you think?

This article was originally posted at http://allampersandall.blogspot.com/feeds/posts/default

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
United States United States
Pittsburgh-based developer.

Comments and Discussions

 
QuestionNice Post Pin
Aaditya parcha30-Dec-13 1:27
Aaditya parcha30-Dec-13 1:27 
Hi micahs,

Thanks for the Nice post..Can you confirm me like is Log4net comes under this?

and can u explain what the below code means

public Employee(): this ( ObjectFactory.GetInstance<icomplainthearer>()){}

what is the ObjectFactory?
GeneralMy vote of 5 Pin
ram828513-Jun-13 1:17
ram828513-Jun-13 1:17 
GeneralMy vote of 3 Pin
Cowwolfe27-Nov-12 4:43
Cowwolfe27-Nov-12 4:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.