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:
- Do all of the constructor argument setup manually (bad idea)
- 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)
- 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.