Poor mans dependency injection
While watching the first of JP Boodhoos screencast series I discovered that a concept that I used in order to introduce testing to developers who work mostly in legacy code (I’m using Michael Feathers terminology here) is in fact a well known pattern.
Let me give you an example. You’ve got a class that you want test, but this class somehow depends on an untestable resource like for instance a webservice. You don’t have some kind of dependency inversion to you’re hand and have to solve this problem on your own. A short example:
public class BillingService
{
public BillingResult DoBilling(BillingData data)
{
Bill theBil = MakeBill(data);
using(BillingClient wc = new BillingClient())
{
wc.DoBilling(theBil);
}
}
}
What I mostly recommend in such a situation is
- Extract or isolate the ugly (Quote from Jeremy Miller) which is the webservice call here.
- Introduce an interface that shields the class from the webservice call.
- Make the whole class rely on the abstraction.
- Use two constructors. I mostly reffered to them as the opened and the closed constructor.
public class BillingService
{
private IBillingSystem _BillingSystem;
public BillingService(IBillingSystem billingSystem)
{
_BillingSystem = billingSystem;
}
public BillingSystem() : this(new BillingSystem())
{
}
public BillingResult DoBilling(BillingData data)
{
Bill theBill = MakeBill(data);
_BillingSystem.DoBilling();
}
}
public interface IBillingSystem
{
void DoBilling(Bill theBill);
}
public class BillingSystem : IBillingSystem
{
public void DoBilling(Bill theBill)
{
using(BillingClient wc = new BillingClient())
{
wc.DoBilling(theBill);
}
}
}
With that you can easily replace the untestable code with some kind of testdouble like a stub or a mock.
public class BillingServiceTest
{
[Fact]
public void DoBilling_ValidBill_BillIsCorrectlySendToBillingSystem()
{
BillingSystemStub billingSystem = new BillingSystemStub();
BillingService billingService = new BillingService(billingSystem);
BillingData billingData = MakeValidBillingData();
billingService.DoBilling(billingData);
//Do some assertions
Assert.NotNull(billingSystem.RecievedBill);
}
}
Today I learned that this is also called POOR MANS DEPENDENCY INJECTION.
P.S.:
Mabe the example is not the best one but I didn’t want to go into something like Foo and Bar again. Besides that it’s only a simplified example. Consider that before throwing eggs and tomatos at me
.
P.S.2:
An alternative to this approach which doesn’t require a new interface is “Extract & Override”.


2 Responses Leave a comment
The aim of Method Injection is, again, to avoid dependencies on the container API. Webservice
And I liked, will be looking at your site.