I\'ve had a certain feeling these last couple of days that dependency-injection should really be called \"I can\'t make up my mind\"-pattern. I know this might sound silly,
Even if you don't change the structure of your program during development phases you will find out you need to access several subsystems from different parts of your program. With DI each of your classes just needs to ask for services and you're free of having to provide all the wiring manually.
This really helps me on concentrating on the interaction of things in the software design and not on "who needs to carry what around because someone else needs it later".
Additionally it also just saves a LOT of work writing boilerplate code. Do I need a singleton? I just configure a class to be one. Can I test with such a "singleton"? Yes, I still can (since I just CONFIGURED it to exist only once, but the test can instantiate an alternative implementation).
But, by the way before I was using DI I didn't really understand its worth, but trying it was a real eye-opener to me: My designs are a lot more object-oriented as they have been before. By the way, with the current application I DON'T unit-test (bad, bad me) but I STILL couldn't live with DI anymore. It is so much easier moving things around and keeping classes small and simple.
Dependency Injection gives you the ability to test specific units of code in isolation.
Say I have a class Foo
for example that takes an instance of a class Bar
in its constructor. One of the methods on Foo
might check that a Property value of Bar
is one which allows some other processing of Bar
to take place.
public class Foo
{
private Bar _bar;
public Foo(Bar bar)
{
_bar = bar;
}
public bool IsPropertyOfBarValid()
{
return _bar.SomeProperty == PropertyEnum.ValidProperty;
}
}
Now let's say that Bar
is instantiated and it's Properties are set to data from some datasource in it's constructor. How might I go about testing the IsPropertyOfBarValid()
method of Foo
(ignoring the fact that this is an incredibly simple example)? Well, Foo
is dependent on the instance of Bar
passed in to the constructor, which in turn is dependent on the data from the datasource that it's properties are set to. What we would like to do is have some way of isolating Foo
from the resources it depends upon so that we can test it in isolation
This is where Dependency Injection comes in. What we want is to have some way of faking an instance of Bar
passed to Foo
such that we can control the properties set on this fake Bar
and achieve what we set out to do, test that the implementation of IsPropertyOfBarValid()
does what we expect it to do, i.e. return true when Bar.SomeProperty == PropertyEnum.ValidProperty
and false for any other value.
There are two types of fake object, Mocks and Stubs. Stubs provide input for the application under test so that the test can be performed on something else. Mocks on the other hand provide input to the test to decide on pass\fail.
Martin Fowler has a great article on the difference between Mocks and Stubs