Answering Questions

I’m awful at returning emails.  It was even one of my new year’s resolutions to reply to emails faster.  The last couple weeks I’ve had a very hard time answering correspondence and I need to catch up.  I’m publishing my answers here because some of them are common questions, and others are things that I just flat out don’t have a good answer for.  Feel free to chime in below with better answers than mine.

 

Won’t Constructor Injection cause a ripple effect? 

I had a question on whether or not using Constructor Injection would create an undesirable ripple effect, and whether or not that problem could be solved or alleviated by using a Dependency Injection tool.  I’m very much biased towards Constructor Injection over using setters for reasons I’ll detail a bit later in the post.  However, using Constructor Injection can easily lead to cases like the class structure below:

class A {
public A(B b) {}
}

class B {
public B(C c, D d) {}
}

public C {
public C(E e) {}
}

public D {
public D() {}
}

Class A needs class B, which needs C & D, which in turn also brings in E.  That’s a lot of stuff to bring in and set up.  You can go three ways:

  1. Do all of the constructor argument setup manually (bad idea)
  2. Use default constructors with no arguments that set themselves up and then open up alternative “greedy” constructors for use in testing (not a bad compromise and a common technique)
  3. Use a Dependency Injection tool like StructureMap to “auto wire” the dependencies together.  Assuming that you’ve specified the default concrete type (and constructor args) for each IService/Service pair, StructureMap can quite happily set up all of the constructor arguments and dependencies to an n-deep level.  In other words, If you ask for an “A” above, StructureMap will work recursively to create an E to inject into C which gets injected into a B which gets injected into the A that you wanted in the first place.  StructureMap (and other tools) look for the “greediest” constructor function to automatically determine what dependencies a concrete class needs.

Part of the reason to use a Dependency Injection tool like StructureMap is to reduce the mechanical cost of composition and loose coupling.

 

What if I don’t need it right away?

Part of the question was about the efficiency of this approach, especially if a dependency deep inside the hierarchy isn’t needed right away, or possible never.  In that case I might opt for using Service Location instead.  That’s what Bellware was calling a “[EDIT]transitive dependency” a little while back.  In my code that would manifest itself as a call to StructureMap like this:  D d = ObjectFactory.GetInstance<D>(); somewhere inside a method in class B above.  Inside of unit tests I can still mock D by using: 

[Test]
public void SomeTest(){
MockRepository mocks = new MockRepository();
D mockedD = mocks.CreateMock();
ObjectFactory.InjectStub(mockedD); // InjectStub isn't the best name. In 2.1 it's gonna be renamed "Inject"
}

Any class that asks for an instance of D is going to get the “mockedD” instance.

 

What about dependencies on File, Path, and Directory?

Another question is how to deal with static classes like File or Path in unit tests?  Is it okay to wrap my own interface around these classes for testing because this feels strange.  I know exactly where this question is coming from.  Like Jeffrey, I happily wrap some sort of IFileSystem interface around these classes and test against mocks of these interfaces.  Does it feel weird?  I suppose, but being able to write unit tests is a good feeling.  Other points:

  • You could use TypeMock I suppose, but that also goes against the advice (that I would second) to only mock interfaces that you control.  IFileSystem up there isn’t a one for one copy of the Path class.  It’s specific to the application’s needs.
  • This is exactly the kind of thing that turns some people off on TDD, or at least integration testing approaches.
  • To make TDD work, and I obviously believe that it does work, you’ve got to be thinking about testability as a matter of course.  Bolting on unit tests after the fact usually doesn’t work all that well.

 

Can StructureMap help with Pluggable Views in ASP.Net?

Absolutely.  Check out Jeffrey’s post on this very subject.  But, before you run off and do that, you might go check out some other solutions like Igloo or MonoRail and see if they’ve already addressed this issue.  To be honest, I’ve never done all that much ASP.Net coding, so I’m not a very good resource for ASP.Net questions.  However, that won’t keep me from saying things like “the WebForms event lifecycle is the most gawdawful, overcomplicated piece of crap MS has ever rammed down our throats.”

 

Where does threading code go in a WinForms app?

Threading code is some of the trickiest code to unit test.  Not impossible, just tricky.  Following Jeremy’s First Law of TDD, threading gets it’s very own set of classes and layer.  I would try to treat threading, even if it’s just a wrapper around the BackgroundWorker, as a separate service in your application in its own right.  Just a rule of thumb, any code that touches into the System.Threading namespace should do nothing but threading manipulation.  I’d probably pass some sort of ICommand interface objects (1 for the real thing and a second for the callback) into the threading service.  All communication with the rest of the system should be through abstracted interfaces. 

The Presenter’s would be responsible for making the correct set of instructions to the threading code service then get out of the way.

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.codebetter.com/blogs/raymond.lewallen Raymond Lewallen

    “the WebForms event lifecycle is the most gawdawful, overcomplicated piece of crap MS has ever rammed down our throats.”

    You can’t say that enough times.

  • Nigel Sampson

    I was pondering question one a few days ago and how this ripple effect would affect testing.

    Then I had one of those “eureka” moments, with using interfaces means that the ripple effect doesn’t exist in testing. With all the dependencies as interfaces (that are mocked in testing) then you’re only testing the class itself and not the entire chain of dependencies. In the application itself a dependency injection tool will alleviate this as Jeremy said.

    With regard to the file system one I’m considering something like IConfigurationSource with a file system implementation that provides streams.

  • Liang

    Jeremy,

    We can create an instance class implemented from “IFile…”, so that the business class can be test easily. But do we need to put that instance class under unit testing? It should be treated as integration test as DAL? Thanks!!

  • http://community.hdri.net/blogs/chads_blog cmyers

    I just had a situation where I had to use the ol’ IFileSystem trick for testing. It worked out *REALLY* well because I could test a lot more things (buffer exhaustion/out of memory, data corruption errors, and all those other weird runtime-only type conditions that you just can’t test when hitting directly against the file system).

    One other added benefit is that, in the future, it will help the various apps that will use this to use a consistent access mechanism for reading and writing files, path mangling, etc. It will help avoid the temptation to use one of the myriad of utility methods incoherently scattered about the System.IO namespace (Here’s a brain teaser for the people playing the home game: How many different ways are there in the .NET Framework to open and read the contents of a text file?)

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    I fixed it Scott.

  • http://www.bellware.net ScottBellware

    Hey Jeremy, I referred to them as **transitive** dependencies. *Transient* is a whole other matter.