Just say no to ‘Poor Man’s Dependency Injection’.

For background, Jimmy Bogard originally posted about the ‘poor man’s dependency injection’ style used in NerdDinner. Not to single out NerdDinner, because there are lots of apps out there doing this. NerdDinner just happened to be the most recent and visible so it serves as a good whipping boy.

Tim Barcz respectfully countered with his post "Why There’s Nothing Wrong With Dependency Injection in NerdDinner.”

I promised Tim a respectful rebuttal to explain why there *IS* indeed something wrong with ‘poor man’s DI.’  That will be forthcoming.  For now, though, it reminded me of a post I did on the altdotnet yahoo mailing list awhile back.

Here’s an excerpt from it for your convenience:

Been thinking a lot lately about how to teach about IoC and how to use containers such as StructureMap to someone who either is coming in cold to DI/IoC or has a vague awareness of what it is.
Personally, the stages I went through (and have seen few other people go through similarly) are:

  1. Replace all (most?) new()’s with ObjectFactory.GetInstance<T>.  You get some immediate benefit out of this and it opens up some new opportunities for your code, but doesn’t even scratch the surface
  2. Move to ctor injection with very explicitly defined instances/pluginfamilies/etc and not using auto-wiring.  Maybe you still even have an old-fashioned C’tor that still satisfies its own dependencies for those times when ‘you might not be using an IoC container’
  3. Embrace auto-wiring, remove non-IoC/DI c’tors and trust fully the container
  4. Start using more advanced techniques like lifecycle management, profiles, convention-based dependency satisfaction, etc
  5. Auto-registration, full trust of the IoC. Thoughts start to pop up like, ‘I wonder if I could get the Container to write my app for me??’

Since I wrote that post, I can now add the following point:

 

6.  Conventional and custom registration. Rather than explicitly registering everything, and more than automatic registration of some things, you develop more complex and conventional ways of registering your objects/services/controllers/etc into the container.  You know you’re in this stage when you’re building your own DSL/FI on top of your container’s configuration model to fit your application’s needs better.

Do you have a 7 or 8 you can add?

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Chad Myers

Chad Myers is the Director of Development for Dovetail Software, in Austin, TX, where he leads a premiere software team building complex enterprise software products. Chad is a .NET software developer specializing in enterprise software designs and architectures. He has over 12 years of software development experience and a proven track record of Agile, test-driven project leadership using both Microsoft and open source tools. He is a community leader who speaks at the Austin .NET User's Group, the ADNUG Code Camp, and participates in various development communities and open source projects.
This entry was posted in IoC, StructureMap. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Andrew

    The one thing some people seem to forget is not everyone is allowed to use an IOC container (for a variety of reasons not worth going in to) plus they are responsible for legacy code which was built without any sort of hand rolled DI.

    So when the choices are Poor Man’s DI or nothing, I choose Poor Man’s DI.

  • Kelly

    As someone who is new to DI I have to completely disagree with this post and agree with Tim Barcz.

    Poor Man’s DI is not the BEST way to achieve DI but that doesn’t mean its a bad way to get into DI. Poor Mans DI has been an excellent first step on the road to using a full on IoC. Poor Mans DI has its advantages.

    Some applications may never get big enough to need an all out IoC. Why can’t we use PMDI in those cases? Instead of writing a post about why you shouldn’t use PMDI, I think you should have wrote about where an IoC is the better choice.

  • Tyler

    It is curious to see others responses as there is probably no way I’ll ever be able to use an IoC container in production at work due to legal concerns as well as the fact that no one will understand it. Kind of a prelude to what will happen if I were to try and use it for real.

    To the others that are responding. Which framework do you prefer and why? Just curious to see what your level of experience with IoC containers is.

    Thanks!

  • http://www.lostechies.com/members/chadmyers/default.aspx chadmyers

    @Andrew: There are exceptions to every rule. If you have an artificial constraint (i.e. management ignorance), then you have to do what you have to do.

    Having said that, it doesn’t make PMDI any less bad. You’ll still run into all the same friction and problems later on. Be sure to remind the management how much time you’ve spent fixing problems with PMDI since they didn’t allow you to use an IOC Tool.

  • http://www.lostechies.com/members/chadmyers/default.aspx chadmyers

    @Kelly:

    I disagree. I have found that IoC is good all but the smallest of applications (i.e. one-CS-file projects). I usually start out thinking that IoC is overkill here and before long, I end up having to incorporate it anyhow at greater cost than if I had just started out that way. I do not agree with the premise that “for many apps IoC is overkill.” I’d say that the exception is no-IOC, and IOC should be the norm unless there are other constraints.

    PMDI will always result in maintenance headache and friction in the end. PMDI is write-one, fix repeatedly.

    “Where IoC is the better choice”, well, it’s *always* better than PDMI. It’s *usually* better than no-DI-at-all.

  • Andrew

    Unfortunately, as Tyler mentioned, Managerial Ignorance is not always the reason why IoC containers are not used. At my company its mainly a legal and regulatory issue.

    In a few posts you’ve mentioned friction with PMDI, maybe it’s because I’ve only really used it on legacy apps (all built in 1.1), but I just haven’t encountered any…at least not to the degree that you insist it will occur.

    I’m not saying don’t use an IoC container (I use StructureMap on my own projects), but the reality is, I don’t always have that option so I’ll take Poor Man’s over nothing.

    Also, as a matter of full disclosure, don’t you think you are a little biased about this issue? Don’t you work for the guy who wrote Structure Map? At the very least, you partnered with him to write FubuMVC, which in a way “competes” with ASP.NET MVC.

  • http://www.lostechies.com/members/chadmyers/default.aspx chadmyers

    @Andrew: If you haven’t experienced the friction of PDMI, it’s more likely you’re simply not aware of it as you probably don’t know how frictionless full IoC container usage can be. I was the same way until I gained a few levels in IoC container usage.

    ‘biased’? By biased you mean ‘experienced’? I *hired* the guy who wrote StructureMap so that, among many other and more important reasons, our IoC usage would be the best it could possibly be.

    In the process of this project, Jeremy has added many new and exciting features to StructureMap and raised the state of the art considerably. I fail to see how this is, in any way, a negative.

    I don’t understand what FubuMVC has to do with any of this. Now you’re just throwing sand in people’s eyes.

  • http://www.lostechies.com/members/chadmyers/default.aspx chadmyers

    @Andrew: I deleted your last comment because it’s just full of nonsense and it’s completely irrelevant to anything. If you want to personally bash me for some silly selfish reason, please go do it on your own blog.

    If you have a salient point to make, please make it. Until then, your only argument is that I’m somehow too arrogant to speak truth about my experience in this matter. Fine, point taken. Thank you.

  • Andrew

    My point is this, and feel free to delete it if you want. You can’t just generalize about all projects and say that eventually PMDI will result in too much friction (like you did in your other post). Because it’s simply not true. At certain parts of a projects life cycle, there just isn’t a need to change the constructor that much, and if there is, you are likely over thinking the problem.

    Of course, it always could (and does) happen, you could get a request to make change that radically changes some of your pre-existing code, when that happens just change it. That is what Resharper is for, but more often than not, changes are small and will never require a constructor change.

    Also, I have no idea where you got it from that you can’t speak from experience, I come to this website for that very reason, but at the same time, you can’t just label everyone who disagrees with you as unexperienced. That is what I had issue with.

    FWIW, I actually never disagreed with you, I think IoCs are great (and even stated that I use StructureMap on personal projects, and have even used FubuMVC quite extensively on a test project for a client before we switched to RoR), but I also think PMDI will also do a a pinch when needed.

  • http://www.lostechies.com/members/chadmyers/default.aspx chadmyers

    @Andrew: I didn’t label you as unexperienced. I just said that if you haven’t experienced the friction of PDMI, you might not have used IoC long enough to understand why PDMI causes a lot of friction.

    Friction is relative, of course. If you maintain 10,000 stored procedures, the friction of changing 250 c’tors every time you add a new dependency is relatively frictionless compared to the stored procs.

    Your arguing exception cases with PMDI. Sure, if someone’s already gotten themselves into the hole and they don’t change the code that often, then the friction of PMDI is nil for now. Should any significant change come along later, it will blow away any small productivity gains that may have been made by using PMDI first instead of a container.

    PMDI is a landmine waiting to explode. It’s possible you may avoid ever stepping on it, but it doesn’t make it any less dangerous to future productivity.

  • Brian Vallelunga

    What sorts of legal/managerial concerns are there that people here can’t use DI? To me that’s like saying I can’t use IDisposable or generics (I’m ignoring .NET 1.1 apps here).

    If it’s an open source issue, can’t you just use Unity? It’s from Microsoft after all. And there’s always the fact that most developers could write a bare-bones DI framework in a couple of days. I’m never going back to pre-DI programming again.

  • Andrew

    Brian,

    Without going into too many details, some industries have very strict guidelines about using Open Source projects, I happen to do 90% of my work for a company within one such industry.

    To just get permission use Log4Net for example we had to have a team of lawyers pour over documents written by my department with justifications for using it, plus they had their own people analyze the code. I’ve been working with this company for eight months but the process started months before I even got here, and we just got permission about a month ago to use it.

    This is for simple logging, getting something like an IoC or ORM approved will take even longer (something I am already working on doing). There’s nothing preventing us from using DI (maybe I wasn’t clear on that originally), just using an OSS IoC Container, which is why I am on the “pro” PMDI side.

  • http://www.twitter.com/MotoWilliams Eric

    We are pretty new to IoC and it makes sense to us. I am doing my best to spread the work in our shop. For my claifification to your item #1, would also replacing our Factory.CreateWidget() also be good areas to *look at* swaping in the ObjectFactory.GetInstance()?

    You’d think our code was written during the industrial revolution with all the factories in there… oh wait it was because we have a lot of iSeries integration :|

  • http://blog.fohjin.com Mark Nijhof

    A bit late to the game I know, but if you are not allowed to use an oss project to get yourself an IoC. Then instead of using the PMDI I think I would go for something like Func from Kzu. Not that one because that is probably also not allowed, but it is relatively easy to recreate that idea and you get a static IoC. You still have to wire it up yourself but switching to an actual IoC is easy, and all new() are concentrated in one place, the configuration of your own Func implementation.

    -Mark