A Quick Introduction to Dependency Injection using StructureMap
Join the DZone community and get the full member experience.
Join For FreeDependency injection is one of those development topics that a lot of developers are curious about but there are still many who haven't taken the opportunity to really learn what it is all about. I will give you a brief introduction to what dependency injection is and how to get started with StructureMap, a very cool open source framework that will help. If you want to dig deeper into what dependency injection is, Martin Fowler has a post on his site you may want to check out.
I have to admit, I had trouble grasping the concept of dependency injection at first and I am not alone in that either. I have talked to several developers that have had the same story. Almost everyone I have talked to that has gotten it can't imagine a time when they didn't use it. It can really change some things about how you approach code (which by the way is not a bad thing).
It was actually like algebra, and programming in general. I just didn't seem to really get it at first and then one day it just clicked and I had that "ah ha" moment. It was StructureMap that did that for me. I had looked at other frameworks, but it was StructureMap that really made the difference.
In a nutshell, dependency injection is exactly what it sounds like it is. It is a method of developing where you "inject" dependencies into your application. This may sound confusing, but it actually is really simple if you take it a step at a time. Let's just jump in with some code and by the time you are done reading this, you should have enough of a jumpstart to keep going and learning more.
Lets start with some setup. We have a scenario where we have an interface with a property and a method:
interface IStuff
{
string Name { get; set; }
void DoStuff();
}
Since this obviously doesn't have any real functionality, lets also create a concrete class from the interface:
public class RealStuff : IStuff
{
public string Name { get; set; }
public void DoStuff()
{
Console.WriteLine("Real Stuff");
}
}
As you can see, the DoStuff method will write some text out to the console. If you were going to use this class, you would create an instance and call DoStuff:
RealStuff stuff = new RealStuff();
stuff.DoStuff();
Since we went through the trouble to create an interface we will want to be able use it as an interface and not require the direct use of the concrete class. This is where StructureMap will help us. To get started with StructureMap, we need to first initialize it. You only want to initialize it once per application, so make sure you put it in the Global.asax of a web app or in the Main method of a console or GUI app. To initialize, you use the ObjectFactory class and call Initialize:
ObjectFactory.Initialize(x =>
{
x.For<IStuff>().Use<RealStuff>();
});
The syntax is really simple. You are basically saying here that when I ask for a IStuff, give me RealStuff. To actually create an instance, we also use the ObjectFactory and call the GetInstance method:
IStuff stuff = ObjectFactory.GetInstance<IStuff>();
The GetInstance method call will use the initialization code to determine what to actually return and the stuff variable will actually be an instance of RealStuff. If I add another line to this and go ahead and call the DoStuff method we will get the following output from the console:
And our dependency injection worked. Our code here only works with the interface, and StructureMap injected the proper concrete class based on our configuration. This has tons of practical applications but one of the most common is in testing. Imagine that we had another class that we want to use in unit testing:
public class FakeStuff : IStuff
{
public string Name { get; set; }
public void DoStuff()
{
Console.WriteLine("Fake Stuff");
}
}
We can set our StructureMap initialization in our tests to the following:
ObjectFactory.Initialize(x =>
{
x.For<IStuff>().Use<FakeStuff>();
});
Now when we run our test on the method that uses the IStuff, we get the FakeStuff instead of the RealStuff. This is a very simplified example but hopefully has been enough to get you pointed in the right direction on using dependency injection. If you check out the StructureMap site at http://structuremap.github.com/structuremap there are more examples and I will be posting more about this topic in the near future.
Opinions expressed by DZone contributors are their own.
Comments