Tripping over logs: A story of Unity - Part 6

Intro

The final post in the series 😊 Get the code here, read comments on unit testing with DI, thanks, references, and further reading!

This is a multi-part series, so here’s the series guide in case you’re looking for the rest:

This is just a final post to wrap up the series—you really should use the above links to get the actual value out of it.

Download the Final Code

Click Here for Download

You’ll need 7-Zip to open it.

My View on Unit Testing with DI

What excited me about DI initially is that it makes testing—and unit testing, in particular—so much better. The problem with any system you want to test is that if it’s tightly coupled, you can’t unit test; you can only do integration testing. By following DI, you’re forced into a loosely coupled architecture, which means you can very easily test your individual components.

Let me give you a real-world story on this, which involved the enterprise system I mentioned in the very first post. It read from system A, did processing, and wrote to system B. The fact that it was tightly coupled meant I couldn’t even fake a message into the system—I had to generate real messages in system A and watch the flow of those messages. After a long time, I dropped MSMQ between system A, the processing, and system B to enable me to fake messages, but even then it wasn’t great—because I needed to rewrite so much code to talk to these new interfaces. Lastly, the processing took many hours to run to completion, so proper end-to-end testing took days. And if a crash occurred, certain processes needed to be started from scratch again.

If I’d used DI for the system, the first thing I could’ve done is written up two mock interfaces and swapped them with real ones using the config. That would mean I could simulate messages easily. System B was in fact MSCRM, which I couldn’t run on my machine (I was using a laptop with Windows XP at the time), so being able to mock the interface to it could’ve meant I could’ve worked on the processing engine without needing MSCRM—i.e., a VM or server.

Next, the tight coupling of methods meant the process had to run its full time, but if I’d implemented DI, I would’ve had each of the individual components of the processing separated out and could’ve tested them individually. Yes, end-to-end processing would still be needed, but I could’ve saved days of testing with this.

I haven’t actually done enough to write a post on this specific topic, so maybe once I’ve done more I’ll be more sure—or maybe I’ll just tell you I was wrong.

Thanks, References, and Further Reading

First off, thanks to you, the reader, for spending time on this series. I hope you drop me a mail / @rmaclean / comment if this has helped you or if you have any questions.

That said, I couldn’t have done it without the great posts I found on this subject—so here are my references:

(Note: Unity is an implementation of this—there are many out there. Scott Hanselman has a list at List of .NET Dependency Injection Containers / IoC.)

Lastly, I couldn’t end this series without linking to the definitive theory on DI by Martin "Wolfman" Fowler—Inversion of Control Containers and the Dependency Injection Pattern. This is a must-read for everyone.

The other must-read is Jacob Proffitt (The Runtime Blog), who is a .NET expert/guru—but not a fan of DI. The reality check you’ll get from him should help balance the DI fanboy crowds.