Dependency Injection

by Jacob 7. August 2007 15:08

Dependency Injection is a design pattern used to abstract a provider from the class using it. Specifically, the calling class assumes responsibility for managing the provider instead of the class being called. Data access is a classic example of a provider that can be injected into classes that use it. If you decide to implement the DI pattern in a data access project, the most common method of doing so is to add an interface parameter on the constructor of each class that needs data access.

A C# Example

A class that accesses data might look like this (if it were programmed by chimpanzees. Or for an illustrative example.)

Original Orders

I’m using the provider factory to pull the connection details from the application configuration file but otherwise this is pretty standard. Getting the data would require creating the object and calling GetData.

CallOrders
Dependency Injection

Dependency Injection would have me change the base class so that I pass an interface into the constructor. In this case, I can probably choose whether I inject the DbProviderFactory or DbConnection, but since DbConnection already has a handy interface, that’s definitely the best way to go:

DIOrders

The benefit to this pattern is that the class is now disconnected from the data provider. The disadvantage is that now my calling code has to handle the provider.

DICaller

Dependency Injection Dissected

Functionally speaking there’s not really that big a difference between the original version and the one with the dependency injected. In all, the actual complexity of the code is a wash in my opinion.

Either way, I’m better off with an abstracted data provider (as handled in the factory classes). Either way, I need to make sure the project is consistent in how it creates the access providers (I’d probably create an internal utility class with a static method to pull down the connection, so don’t let the extra lines above distract you).

That said, dependency injection doesn’t scale well and creates opportunity for future versioning pain should you find you later need to add providers. What if, for example, I need two data connections instead of one for my class because some of my data is being pulled from a second data source. I would then need two parameters on my constructor. I could move the injection point to the methods instead of the constructor so that only the affected methods have the signature change (a not-uncommon DI method if only a small number of methods have the dependency), but generally that just pushes my problem down to where it affects more code.

And yeah, providers shouldn’t change often and there shouldn’t be more than one or two so this isn’t a huge concern. I just hate breaking encapsulation and even a small hit to your orthogonality can be significant if you find you ever have to change it.

Dependency Injection’s Natural Domain

The real reason that DI has become so popular lately, however, has nothing to do with orthogonality, encapsulation, or other "purely" architectural concerns. The real reason that so many developers are using DI is to facilitate Unit Testing using mock objects. Talk around it all you want to, but this is the factor that actually convinces bright developers to prefer DI over simpler implementations.

I do wish that people would admit that DI doesn’t have compelling applicability outside of Unit Testing, however. I’m reading articles and discussions lately that seem to take the superiority of DI for granted. And I’ve read mock object examples that seem a little bit condescending about dependency injection--as if your projects should already incorporate this technique. I wonder if this is a defensive reaction because the authors of the examples don’t want to have to justify making you fundamentally alter your coding habits and re-write all of your existing code just so that you can use their pet objects.

Superior .Net Mocking

All of this becomes particularly exasperating in the dead silence regarding TypeMock. I blogged about this product as soon as I found it because their claims are simply stunning. TypeMock claims to allow you to mock objects used by your classes without having to expose those internal objects at all.

I have completed a project using TypeMock for my Unit Testing and I can verify that they are correct.

No interface creation or injection required. No dependency injection at all. No change to how I want to create my objects. No orthogonality issues hidden like a time-bomb in my code, however tiny. TypeMock uses reflection to intercept pesky calls and has robust assert, parameter, return object and verify options. The ability to select which calls to mock and which to let the original objects handle is an outstanding unlooked-for bonus.

Best of all, TypeMock is free to use. Yeah, it’s easier to use their professional and/or enterprise products because there are improved ease-of-programming objects in those editions, but their community edition has all of the actual functionality and none of the cost.

What Gives?

So tell me; what gives? Why the resounding silence around this tool? If it works, why isn’t every .Net developer on the planet talking about it. If it doesn’t why aren’t they reviling TypeMock for taunting us so cruelly? I’m serious. Why isn’t this sucker taking the Unit Testing space by storm? And why am I still hearing about the virtues of a pattern whose sole perceptible benefit is allowing mock objects in Unit Tests?

Tags: , , , , , ,

Programming | Software

TypeMock Fanboi Update

by Jacob 21. June 2007 15:18

Fanboi Phil left a comment to yesterday's post saying that he'd heard good things about TypeMock, but that it wasn't free, so it's not useful in OSS situations. That got me wondering because I could have sworn that the Community Edition of TypeMock was free. Going over their website, it looks like that edition should be free, but they never come out and actually say so. The trouble is that there's a "30 day evaluation license" on the download page but that's not at all the same as being free.

A little digging reveals that the download of the TypeMock framework includes a demo mode that allows you to use all the Enterprise features, but for a single test only. Their price page doesn't list the Community edition at all. I just couldn't find whether the Community edition is truly, concretely free just from poking around. That information just isn't present. Since I was curious and all, I shipped them an email and asked outright, bringing up the OSS angle specifically.

In a pleasant surprise, I received an answer in just a couple of minutes. Here's the relevant portion:

The Community Edition is free to use! And you can use them on Open Source projects.

Good to know. I wish it were clearly stated on the website, but at least the impression I got wasn't misleading.

On a Related Note

The TypeMock front page has a link to Eli Lopian's blog (he's their CTO). I bring this up because one recent post demonstrates using TypeMock to test a form close event that throws up a confirm dialog. Now, I don't know about you, but a MessageBox.Show() call is practically untestable as far as I can see. Wrap it in an interface? Ugh. You'd want a broader UI communication interface and I cringe as I consider implementing such a thing.

Using TypeMock makes this relatively painless, however. His examples use objects only available in the Professional edition of TypeMock (the recorder objects), but the technique he uses is applicable in the community edition as well—just a little more complex. Nothing like what you'd have to do with dependency injection, though. The key is that using TypeMock, you can override any method of any type during your test. That's some mighty reflection Fu there.

Technorati tags: , , ,

Tags: , , ,

Programming | Software

Mocking Developments

by Jacob 20. June 2007 16:45

mocking I like unit tests, at least in theory. Having solid unit tests means being able to determine if small changes to a system produce unexpected results much sooner in the development cycle than we could before. The larger your system, the more people developing it, and the longer you expect you'll have to support it, the more useful unit tests are. Like nightly backups or source code control, unit tests are preventative care that has a continuing cost for no immediate, trackable benefit.

The biggest problem with unit testing, though, is being able to test small units of code in isolation from buried dependencies. The typical example of required isolation is when your project is using something like logging or database access (or both). In one of my projects, for example, I have a static Utility class with a CreateLog method that puts an entry into windows' application log. Testing any method that calls this baby is going to be a pain unless I want my application log to fill up with useless test chatter.

Using Mockery to Avoid Undesired Methods

So far, the answer to this tension between complete testing and the side effects of extended dependencies is to use mock objects that stand in for your heavy-weight objects. Mock objects only pretend to do what the actual object does so while your tests think that a log has been created (or a database updated, etc), it actually hasn't.

Unfortunately, the state of the art in mock objects leaves a lot to be desired. Here's what people tell me I would have to do in order to unit test without cluttering up my application log:

  1. Redesign my Utility class so that instead of using a Log object, you can pass it an interface for a log object. This is called "Dependency Injection". More on that later.
  2. Since my Utility class is static, this means I have to either mess with swapping out a singleton or pass the ILog interface into my CreateLog method. Or make it an instanced class, of course.
  3. Use a mock framework to create a special instance of an ILog that doesn't actually do anything except parrot back what you tell it to when certain conditions are met (methods called etc.).
  4. Call the object I'm testing, passing in the ILog instead of whatever it was using before.

Simone Chiaretta gives an excellent example of using Rhino Mocks to mock an NHibernate repository where you can see this technique at work.

Dependency Injection Objection

Here's the thing: Dependency Injection sucks. I don't like it. It exists solely to overcome this weakness of Test Driven Design and it strikes me as a huge kludge for the sake of purity. It intrudes into all aspects of development from design to QA and requires that you re-architect any systems that were created before you got religion. Ick.

Phil Haack had an article yesterday about HttpSimulator, a new project he put together that helps simulate HttpContext objects for unit testing. This is a very clever way to overcome embedded dependencies for a common .Net subsystem without resorting to dependency injection.

Outside of something like Phil's solution, dependency injection seems to be the best way to get full unit test coverage in large projects that have broad effects or latency-prone subsystems, though. I hate having to acknowledge that. Interfaces have their uses and all, but the prospect of creating an interface wrapper for every object I want to skip in unit tests and then having to make sure I can hot-swap important objects using these interface wrappers is a mountain of work just to extend unit tests a little. Blah.

TypeMock to the Rescue

Still, unit tests are important enough that I wanted to try them out on a project or two and see how bad it really is to implement dependency injection and have a project that has 100% unit test coverage. Researching different mock frameworks was depressing, though. There are quite a few of them and they all have the same pattern. I thought I was truly doomed. Then I stumbled across TypeMock.

It looks to me like they've developed a system much like Phil's HttpSimulator, only more general in nature. TypeMock allows you to declare a type (hence the name, I'm guessing), and let your test know that calls to that type are going to bypass the called method altogether. It allows you to check what parameters are being passed in and setup what results will be returned—the kind of things you'd expect a mock object to do for you. All without the dependency injection nonsense. Sweet!

Their professional and enterprise editions even have some cool recorder objects that implement IDisposable and allow you to use extremely clear syntax with fine control over the mocked objects and methods. Those editions run a couple hundred bucks, though, so I'll probably have to give them a pass. Their community edition is free, however, and while the syntax is a bit more involved (and obscure), it still gives you the ability to avoid implementing a plethora of wrapper interfaces. I love that.

Now Wait Just a Doggone Minute

It's not all roses, of course. It looks like in order to work properly, you need to run their TMockRunner.exe program with your unit test framework as a command line argument. I'm thinking this is what enables them to penetrate so deep into your classes. This means that you have some setup to do if you want to integrate TypeMock into your development environment. Still, that's a lot less work that creating a whole new paradigm and then exposing all your dependencies, I'm thinking.

Since I've only just installed TypeMock, I can't tell if it actually does all it claims to do or if it's a buggy piece of crap. For all I know, it's just so much snake oil making promises it cannot actually keep. We'll see about that here shortly.

At any rate, I like what I've seen so far and I really hope it turns out to be as nifty as it looks. I'll post updates here as they occur to me going along.

Tags: , , , , ,

scruffylookingcatherder.com

Information

    Recent Posts

    Calendar

    <<  September 2010  >>
    MoTuWeThFrSaSu
    303112345
    6789101112
    13141516171819
    20212223242526
    27282930123
    45678910

    View posts in large calendar
    Disclaimer
    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2010 Scruffy-looking Cat Herder