jordan.terrell
Just trying to make sense of things...

Dependency Inversion vs Type Mocking: Debate

Monday, 20 August 2007 13:08 by jordan.terrell

In case you haven't noticed, there is a bit of a debate going on over Dependency Inversion and Type Mocking, and the merits of each approach.  Many bloggers have started to weigh in on it; so I thought I would join the fun.

I favor Dependency Inversion. This is not to say that both approaches don't have benefits - they clearly do, and neither side has produced completely ideal results, as was well stated by Aaron here:"...neither sides of the camp is producing Silver Bullets."

Jacob Proffitt (the originator of this discussion) has repeatedly sung TypeMock's praises - and rightly so, as it is a very powerful mocking tool. The fundamental problem I have is this: I refuse to allow my overall application design to be coupled to the availability of a commercial tool or product.  My main goal, and hopefully the goal of all well reasoned developers out there, is to create application where the components are loosely coupled from each other, and the overall design is decoupled from the tools used to make it.  Relying on TypeMock to achieve this seems like an dangerous bet.  I can still achieve this loose coupling without any tools when I apply Dependency Inversion - it may not be the most enjoyable and I normally use tooling; however, I'm not required to, and should I change my tooling in the future it will be likely be less effort to do so.

One approach that I've used in the past is to use ambient service locators, similar to the Scope<T> sample on MSDN.  This allows you to achieve some of the "aesthetic" (for lack of a better word coming to mind) qualities that I think both sides are striving for.  You can still "inject" your dependencies - but you can do so without relying on the traditional approaches (constructors, methods, and properties).  I strongly recommend you take a look at that sample.

Above all, it is the well-established, time-tested principles that we should want to stick to.  Letting a vendor’s product drive your design and how you achieve adherence to those principles may be an unwise approach.

Comments (7) -

August 21. 2007 15:30

John

So you refuse you application to be coupled to .NET, to windows, to Oracle?

John

August 21. 2007 16:32

David Meyer

I think it is implied that his statement in bold excludes tools or products that are essential to the purpose of the software in question.  For instance, software that is purposed to run on Windows will implicitly rely on the availability of Windows whether or not it is coupled with it in code.  At the same time, it would be good practice that the "overall application design" does not rely on Windows.  The Windows-specific functionality could be encapsulated and its dependency injected, making it a 'loose coupling'.  This way, the code could easily be adapted for use with another operating system.  The same goes for Oracle.  If the overall application design relied on Oracle and Oracle went out of business or otherwise became no longer available, what then?  Of course, you would want to design your application so that another data source could be used if it was necessary in the future.

I think his point is, and I agree, that dependency injection is advantageous because it can be done without depending on any tool or product, whereas TypeMock is a tool that may or may not be supported in the future and its use would influence the "overall application design", making it tightly coupled.

David Meyer

August 23. 2007 15:44

Jordan

John – I think David replied very well. I was not implying that I wanted to decouple my application from their target platform – however, I do strive to decouple the application/OO design characteristics (e.g. class hierarchy, interface definitions) of my application from being dependent on any tool or product.

Jacob stated that he does not apply Dependency Inversion in the design of his applications because he can use TypeMock to achieve “loose coupling” within the context of his unit tests. I strive for loose coupling outside the context of my unit tests because it enables change. I’m always open to new, or better understood older, approaches – but from my experience using Dependency Inversion has saved me so many times, especially outside of testing scenarios.

Jordan T.

Jordan

August 24. 2007 13:56

John

What you are saying now is the same song as everyone else - that it enables change which in other words means - we don't really need it now, we hope it will help in the future.
I personally like to implement it WHEN I need it. That means that when I find a good reason to use DI or Singletonthen I use it. TypeMock gives the freedom to do this - and yes this has a lot of value in my team.

About your design begin decoupled from your tools - take a deep breath and a step back and see if you are introducing DI into your code ONLY because your tools require it. (Are you making that method vitrual public because you really need to allow consumers to call and overload that method and take the performance hit or is it so that your mocking
tool can handle it?)

It is the price of the tool that you are worried about? The commerical support?

The fundamental problem I have is this:
<b>I refuse to allow my overall application design to be coupled to the <strike>availability</strike> ABILITIES of a <strike>commercial</strike> tool or product</b>

John

August 24. 2007 14:59

David Meyer

John - You basically just knocked protected variance.  There is a reason to anticipate future changes and plan for them in your code, because it reduces the amount of work necessary to make those changes later at very little expense at the present.  And the truth is, software always changes.  Change-friendliness is one of the goals of design, and it is one of the things that makes code good code and not just mediocre "it works" code.

Dependency injection is one way to protect variance.  It is a tool in the designer's arsenal, with its proper uses, advantages, and disadvantages like anything else.  It has a use in testing scenarios, but that is just one application.  It is also many times used internally; it may not even be exposed to other assemblies.

David Meyer

August 26. 2007 00:40

Jordan

After thinking about John's questions for a while, I wanted to reply as a seperate post - stay tuned!

Jordan

August 27. 2007 11:14

Jordan

John/all - My response post is up:

blog.jordanterrell.com/post.aspx

Jordan

Comments are closed