Click here to Skip to main content
12,624,887 members (37,713 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

25.3K views
8 bookmarked
Posted

Dependency Injection in .NET

, 25 Feb 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
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:

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:

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:

//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:

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);
}
}
<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?

License

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

Share

About the Author

micahs
Chief Technology Officer
United States United States
Pittsburgh-based developer.

You may also be interested in...

Comments and Discussions

 
QuestionNice Post Pin
Aaditya parcha30-Dec-13 2:27
memberAaditya parcha30-Dec-13 2:27 
GeneralMy vote of 5 Pin
ram828513-Jun-13 2:17
memberram828513-Jun-13 2:17 
GeneralMy vote of 3 Pin
Eric Z-man27-Nov-12 5:43
memberEric Z-man27-Nov-12 5: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.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.161128.1 | Last Updated 25 Feb 2010
Article Copyright 2010 by micahs
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid