Hanalei, Hawaii Tuesday, February 09, 2010

200 Page Manual on Inversion of Control (plus or minus 199)

I’d like to preface this treatise with an appeal to those of lesser intellect – please close your browser now. The concepts you read below are quite high-minded and we have a secret handshake you don’t know. We are “The IoC Community” and we rock the concepts yo.

For those who haven’t read the 200 page manual on IoC – well here ya go. If your little brain can’t handle the complexities of this post might I suggest turning on Howard Stern and Spolsky at the same time, full volume, and holding your breath until you see patterns in the air. This usually helps when wondering WTF Joel is talking about.

Let’s take a walk on the Cool Kid side of the street and see what Inversion of Control is all about…

I’d like to preface this treatise with an appeal to those of lesser intellect – please close your browser now. The concepts you read below are quite high-minded and we have a secret handshake you don’t know. We are “The IoC Community” and we rock the concepts yo.

For those who haven’t read the 200 page manual on IoC – well here ya go. If your little brain can’t handle the complexities of this post might I suggest turning on Howard Stern and Spolsky at the same time, full volume, and holding your breath until you see patterns in the air. This usually helps when wondering WTF Joel is talking about.

Let’s take a walk on the Cool Kid side of the street and see what Inversion of Control is all about…

The Setup: My Blog

So I’m building my blog (more on that later) and it makes for a really good demo since most people understand blogs. So I’ll use it for this discussion. Let’s pretend I have a PostController (using MVC) and this thing shows Posts.

I have a single action called “Index” that grabs data from my database and sends it down to my view (let’s pretend I’m using Linq to SQL):

public ActionResult Index(){
   var db=new Model.DataContext();
   var posts=db.Posts.Where(x=>x.IsPublished);
   return View(posts);
}

Groovy. Now let’s get on with this…

Analysis

What I’ve done here is pretty typical, and what you would see in any demo given at a Microsoft conference. The person writing this code can easily invoke the “This is a demo/small app so shutup” rule when the Cool Kids cry foul – and that would hold most likely as it would be either Hanselman or Scott Gu giving the demo and those guys have swagger like that.

There’s no need for complexity at this point – which is true, however it should be noted that we’ve incurred what’s known as “Technical Debt” – which is akin to repairing a go-kart with duct tape. Like debt, you could live with it, but more than likely it will cause you problems as you build out your app.

The Next Step: Making Sure It Works

Typically what you might do, as a developer, is to hit F5 (Debug/Run) to see if data appears on your page. It’s still magic to me after all these years to see data from my DB hit the screen – I dig that rush and for a moment my little itch is scratched and I feel good about myself. I see data there – so it works.

But then I begin to think – do I really want to hit F5 every time I want to make sure this page runs right? I’ll appease the Cool Kids and add a test:

[Test]
public void Post_Should_Show_Posts(){
   var controller=new PostController();
   var view=controller.Index() as ViewResult();
   var posts=view.ViewData.Model as IEnumerable<Post>;
   Assert.IsGreaterThan(0,posts);
}

 

What’s this test telling you if you put your programmer’s hat on? The title is a bit misleading as we don’t know what the view will actually “Show” – moreover we’re just testing that we have posts.

This test will fail – immediately – and it will keep failing no matter how much code we write. Why? Because I have no data in my database and this test will fail until I add some. Being the impatient type I add a record to my DB and my test passes.

If your geek senses are tingling – that’s a good thing! This test is pointless to say the least – what “unit of functionality” is it testing? None. And if you look at this a bit longer you’ll start to realize that I’m not chanting or smoking a secret mix of techno-herb and sassy weed – I’m just using common sense and basic coding principles. What happens if I remove all records again? The test fails. Does that mean my Controller won’t show posts? Not at all – and this is one main reason the People Who Like Testing (Cool Kids) advocate against hitting the database.

Well what’s the point of testing Controllers then if it’s this hard!

It’s not hard – it simply requires you to look a bit further and use some tricks – that’s all.

Rewind and Refactor: Using an Interface

Interfaces are scary to many developers at first – they seem rather pointless until you actually use them. In this sense they work perfectly since I don’t want to talk to my database at all – what I really want in my Controller is the ability to get data from *somewhere* (not necessarily a SQL Database). That’s the important part – and yes it’s an abstraction – but that’s one step towards the idea of “Loose Coupling”.

When I wrote my initial Controller Action above (Index), I planted data access code right in it from Linq to Sql. In doing that I also made a decision that was explicit: whenever I use this controller, I also need to make sure I have my Linq to Sql classes set up and pointed to my Post database. This is called “coupling” and you can think of Linq To Sql and your PostController on a date, having babies if that helps.

Let’s pretend I made an interface (IPostRepository) with a single method called “GetPosts()” which returns an IEnumerable<Post>. Now I can use it instead of Linq:

IPostRepository repo;
public ActionResult Index(){
   var posts=repo.GetPosts();
   return View(posts);
}

This is a good first step – but how does it help me? I can’t instantiate an interface can I? So how the heck to I make this work?

Next Step: Dependency Injection

Put in plain English: our PostController has a dependency on data from the IPostRepository – it needs it to function (which is a dependency sort of like your college roommate needed to wake-n-bake in order to get moving).

We could just implement our interface in a concrete class (let’s call it SQLPostRepository since we’re using SQL Server) somewhere and instantiate that:

IPostRepository repo;
public ActionResult Index(){
   repo=new SQLPostRepository();
   var posts=repo.GetPosts();
   return View(posts);
}

Now the code works, but we’ve traded one dependency for another (on SQLPostRepository) – what did we gain here? Well nothing actually – and the Cool Kids are getting pissed.

What we should do is to allow the calling code to specify this dependency when creating the class, defaulting to the SQLPostRepository if nothing was set:

IPostRepository repo;
//injectable constructor
public PostController(IPostRepository postRepository){
   repo=postRepository;
}

//default
public PostController(){
   repo=new SQLPostRepository();
}

public ActionResult Index(){
   var posts=repo.GetPosts();
   return View(posts);
}

This works, and now we can test this by sending in a fake repository (made up of in-memory lists) or we can use mocking, which basically “lies” about stuff. I’m going to sidestep the testing aspect here (easily will derail the post) as I want to stay on Dependency Injection and Inversion of Control.

Analysis.

On the face of it we’ve “loosened things up” which is always good as now we can plug in SubSonic instead of Linq to Sql if we wanted to, or next year we can use the [Groovy New ORM] that’s all the rage.

There is a problem, however, with “Naked Dependency Injection”, and that problem is that Controllers typically have more than one dependency. There might be logging involved, email, a comment repository, user repository, etc and you’d have to inject each of these (and update all the calling code when you change stuff).

It’s pretty easy to end up with “Constructors Gone Wild” by following this pattern, and on occasion you can end up with recursive construction – which is really ugly and a maintenance nightmare.

The Answer: Inversion of Control

It’s a strange name – Inversion of Control – it sounds like you’re turning your app inside out. Here’s what it means:

Normally, when your class needs to use another class to do something it will instantiate an instance of that class, use it, and then discard it at some point. In this case our PostController class is controlling the instance of the IPostRepository – determining when it gets created and how. All these decisions being made for our IPostRepository – isn’t that just a bit presumptuous!

Inversion of Control does the exact opposite. You have a thing called a “Container” that instantiates the classes and controls their lifetime (according to some rules you set) and it hands them out when asked for. In our blog app the control is removed entirely from the PostController and is “inverted” – handed completely to the container which tells your PostController “this is the object you’re going to get  and you’re going to like it”.

The IoC container is essentially a big playground of objects just waiting to be used and reused. As you can imagine, there’s a lot of freedom when your objects are cut free like this – you can setup all kinds of rules for them and even control their lifetime. Want to make one a singleton (yuck)? You can do this easily with a half-line of code. Want to set an object’s lifetime to that of the request? Same thing.

I’ve used StructureMap a lot as it’s what I know – but Ninject or any other framework is pretty easy to pick up, no Big Brain required – so that’s what I’ll show you below.

The first thing you do is to tell StructureMap what type of class you want when a given interface is used in a constructor. You do this in a thing called a “Registry”:

    public class BlogRegistry : Registry {
        protected override void configure() {
            
            ForRequestedType<IPostRepository>()
                .TheDefaultIsConcreteType<SQLPostRepository>();
           
        }
    }

 

Then, in your Application_Start you call it:

protected void Application_Start()
{
    StructureMapConfiguration.AddRegistry(new BlogRegistry());
}

Now when you want to use it, you ask StructureMap for an instance of the object:

var repo=ObjectFactory.GetInstance<IPostRepository>();

 

On the face of it this might seem like a lot of code for nothing – and it’s a bit true. IoC is an investment in your application – not a direct deposit. What you gain is the ability to “unhinge” your classes from one another, reusing them in other applications as needed.

Most importantly, as you’ll see below, I’ve lost all of my “technical debt” and not many things are more fun than being debt-free.

In the case of my blog application, I can override my ControllerFactory and ask StructureMap to build my Controllers for me – this reduces my examples above to this:

IPostRepository repo;

public PostController(IPostRepository postRepository){
   repo=postRepository;
}

public ActionResult Index(){
   var posts=repo.GetPosts();
   return View(posts);
}

 

Now the Controller knows nothing of any implementation – which is awesome.

Summary

If you’d like to know more about DI/IoC (and some details on how to hook it up to an MVC App), I did a full hour’s video cast with Jeremy Miller (creator of Structure Map) and you can watch it here: http://www.asp.net/learn/mvc-videos/video-366.aspx. It’s about an hour long and I think the best of the entire MVC Storefront series.

It took me just over an hour to write this post – how long did it take you to read it? Does IoC make more sense to you? Regardless if you think it’s worth it (you might think it’s crap) – is it too high-minded? Too complex?

IoC containers take a simple, elegant, and useful concept, and make it something you have to study for two days with a 200-page manual. I personally am perplexed at how the IoC community took a beautiful, elegant article by Martin Fowler and turned it into a bunch of complex frameworks typically with 200-300 page manuals.

Am I a whole lot smarter than you?

I think that people who use IoC containers are (A) very smart and (B) lacking in empathy for people who aren't as smart as they are. Everything makes perfect sense to them, so they have trouble understanding that many ordinary programmers will find the concepts confusing. It's the curse of knowledge. The people who understand IoC containers have trouble believing that there are people who don't understand it.

Is it harder to read my final PostController versus my “Naked DI” Controller above?

I believe that if you use IoC containers, your code becomes, frankly, a lot harder to read. The number of places you have to look at to figure out what the code is trying to do goes up by at least one. And somewhere in heaven an angel cries out.

I mentioned in my last post, in the comments, that I’m no stranger to disagreeing with Joel. It crosses the line, however, when he advocates idiocy – the notion that *you* are too dumb to figure this stuff out.

Are you?


Andrei Rinea - October 8, 2009 - Excellent post Rob!

It took me 7 minutes to read it and understand it. I was following these patterns except the IoC container part. I was, as you was saying, going nuts with controllers. Now I can simplify my MVC apps.

Thank you!
Andrei Rinea - October 8, 2009 - sorry, "Constructors gone wild".
Liam McLennan - October 8, 2009 - Nice intro to IoC. It doesn't get much simpler than that.

I do agree with one of Joel's points that you quoted - that the people who use IoC containers are lacking in empathy for people who aren't as smart as they are. I suspect that they think of it as not wanting to sacrifice quality design to appease the set of developers who aren't interested in learning.
phenryll - October 8, 2009 - Thanks a lot for your excellent article Rob.

It is straightforward and ease people of the burden of reading a 200 pages manual :ppp

Actually, watching your video is the next way to turn. It is downloading by the way lol
Stephane - October 8, 2009 - Great tutorial and detailed explanation of the purpose of IoC.
But is it me or you jumped ovre the step that shows how to actually implement it? :

"I can override my ControllerFactory and ask StructureMap to build my Controllers for me".

That seems pretty straight forward for any developer already using IoC, but as the post is meant to be a manual, I expeceted to see that here too.
paul - October 8, 2009 - which is akin to repairing a go-kart with duct tape :o)

Hate those wobbly go-karts man. All seems good then the wheels fall of at top speed in the middle of the race.
MartinHN - October 8, 2009 - It does make sense, and it advocates good design and coding. We've said for years that we should apply loose coupling in our applications, but sometimes I just think about scenarios where you'd actually change, e.g. your database layer?

I agree with you on technical debt and DI vs Naked DI, and it really is an investment. But will that investment ever pay off if you don't change your database?
Romain Verdier - October 8, 2009 - Good post.

Just a minor detail: in a sample you named your constructors PostRepository instead of PostController.
Duncan Smart - October 8, 2009 - tl;dr

...just kidding!
MrTea - October 8, 2009 - "I agree with you on technical debt and DI vs Naked DI, and it really is an investment. But will that investment ever pay off if you don’t change your database?"

But the investment is minimal. You start writing some new functionality, so you start with a test. The test needs to access the repository so you test using the repository interface (and a fake/mock).

You feel the speed because you're testing logic, without any concerns about data access etc. You can quickly change the tests, and the logic and check if it still works.

Actually the "investment" is probably a lot less time consuming than having your data access code embedded in the controller somewhere, because with that scenario you will a)spend ages trying to write tests around it and hitting brick walls or b) spend ages firing up the browser and clicking to test that things act as they should.

On the point of change, I am in the middle of changing an app from Subsonic to NHibernate (sorry Rob, nothing personal just keen to try all the options) and know that as long as the implied contract (as defined by the interface) is maintained, everything will continue to work (and my tests will help to verify that).
Nilesh Gule - October 8, 2009 - hi Rob,

This is a wonderful article on Dependency Injection. I have been using Spring.NET for injecting dependencies in my projects. I was thinking of writing a small post myself on dependency injection, which I might still do. But your's is quite an elaborate article on this topic. Thans for such wonderful writeup.
Rob Conery - October 8, 2009 - It's in the video - I should have pointed that out :)
Rob Conery - October 8, 2009 - Thanks - fixed!
Rob Conery - October 8, 2009 - Oh yes. It's not just for DBs but any type of code you put behind an interface - think about the long running apps you've had (long development) where you've had to switch stuff out. It's painful right? Interfaces and IoC can help with that.
Rob Conery - October 8, 2009 - Heh - no worries. I'm replumbing Kona with NHibernate right now too :)
jdn - October 8, 2009 - I can't figure out how to close my browser. ;)
Donald Burnett - October 8, 2009 - Great info. Thanks..
Jakob Gade - October 8, 2009 - Hi Rob,

Avesome post, I'll be using this for training the developers in our company on IoC. You made me laugh several times, and you explain it plain and simple. DI and IoC is not for the cool kids only, it's actually the most important principle/pattern you can learn as programmer. And it's NOT rocket science - a fact you demonstrated here perfectly.

Thanks.
Romain Verdier - October 9, 2009 - Hey, you missed one in the last sample :)
PM-SilverCrux - October 9, 2009 - Excellent Article! This is as simple as it gets.
Adam Schroder - October 9, 2009 - Great post as always Rob. I can't write code without using them now. Its the first thing I plumb into my apps.
Danyal - October 9, 2009 - This is the best introduction to IoC I've read, no doubt helped by the simmering Conery-Spolsky tensions.

These will no doubt all be resolved by Joel one day, probably when he issues a Uwe Boll style combat invitation, asking everybody who uses techniques he regards as complicated to come down personally to his white padded "boxing ring".

Until this year, though, IoC might have been regarded as slightly mysterious by people, including myself, because of the absence of introductory articles such as this.

But recently exponents such as Scott Guthrie, Castle, and yourself have helped a lot by realising that very basic introductions are needed for the duct tape masses.
Dan Elliott - October 9, 2009 - To the tune of "Row, row your boat!"

"Joel Joel Joel you float,
ideas of idiocy,
Along comes our RobCon,
who makes it clear to me!"

Cheers,

Dan
Richard Kimber - October 9, 2009 - Hi,

Is it possible to use a technique similar to your StructureMapControllerFactory for webforms?

Rich
Kevin Sheffield - October 9, 2009 - absolutely, that Application_Start function is a function in the Global.asax
Richard Kimber - October 9, 2009 - Thanks for the reply Kevin. I was thinking in terms of the actual ASPX page.

I've been using so called lazy injection for a little while now, which has left me with a number of ASPX code behind pages with overloaded constructors. I'd like to delete the default constructor in favour of a StructureMap implementation similar to what I use in MVC. Is it possible through use of a Module (possibly) to override the default instantiation of an ASPX page?

Rich
Paul Jackson - October 9, 2009 - Awesome post, thanks Rob!

Rob says:
“I’ve used StructureMap a lot as it’s what I know – but Ninject or any other framework is pretty easy to pick up, no Big Brain required”

You imply that all IoC containers are created equally .. is that true? Is it really only about familiarity?
Kevin Beridge - October 9, 2009 - Nice clear post. But I'm curious what your thoughts are on IoC vs. Service Locator.

I've personally always preferred service locator because it involves so much less magic.
Nicholas Piasecki - October 9, 2009 - That makes sense. So here's the part that HAS been rocket science and generally beyond me.

I totally get it when it comes to things like "injecting" a repository into a controller. But then I see examples going haywire, with people giving examples of INotificationSender or IEmailTemplateProvider or IPizzaOven. It just so happens that an object in my domain model might want to send a notification, send an e-mail, or bake a pizza in response to an event. How does that object get a reference to the object that it needs?

Do I have an insane constructor party, where the IoC container lives at the "top" of the application and any dependencies are passed from object to object like a hot potato (aka "new SillyController(ISallyRepository repo, INotficationSender notifier, IEmailTemplateProvider emailer)")? What if the objects at the top of the application don't even "need to know" that my domain object has this dependency?

Do I wrap my IoC container in a static class and reference it anywhere I please? Isn't this pretty much just a service locator then? Why wouldn't I just use that pattern since I could at least see it in a debugger?

Do I move the notificaton-sending, e-mail-sending, pizza-baking functionality to the "top" of the application near where the IoC container lives (that is, say, in the controller)? That seems to degenerate into the Transaction Script pattern with an anemic domain model.

THAT is the part of IoC that seems to require the 200-page manual, and I will admit that I just don't get it. Help!
Ryan Roberts - October 9, 2009 - Unfortunately not, which is why the whole ugly walk the control tree and set the properties trick is needed. I don't know if they have a better DI story in 4.0, but I doubt it.

Much of MVC too is unfortunately resistant to good DI use when you start spelunking round in modelbinders and such. I suspect that MS demo poor mans DI actually does effect design decisions.
Richard Kimber - October 9, 2009 - Thanks Ryan, I suspected as much. It looks like I'll be over using GetInstance in Webform projects.

Rich
Jim - October 9, 2009 - Rob--I liked this post. I wish more developers would explain concepts like this.
Ryan Roberts - October 9, 2009 - Pretty much, I have used autofac, structuremap and winsor(a little), there's a lot of cross pollination between the projects that means they track each others features even if they work slightly differently.
Ryan Roberts - October 9, 2009 - The Cool Kids usually advise that domain objects should not have direct service dependencies, you can decouple them using the domain event pattern http://www.udidahan.com/2009/06/14/domain-events-salvation/.

In your domain object you would do something like:

DomainEvents.Raise(new CustomerBecamePreferred() { Customer = this }).

A handler object that has the appropriate services injected into it would then be responsible for performing something like an email notification. Which if you think of it isn't really the responsibility of a model. With that level of decoupling you can just fetch them from persistence and not worry about injecting services into them.

Also it sounds like you might be overusing factory rather than request(assuming a webapp)scope. If your services are instantiated per-request just take a dependency on the highest level interfaces you need.

Things do quickly get out of hand when you start newing things up yourself in a highly composed system. I recently went there painfully with some fluent object builder stuff.
Dan A - October 9, 2009 - I read this, and what you said makes sense to me, but I still don't necessarily buy into the whole idea. I'm not sure if this makes me a Joel advocate or just plain dumb.

Actually, its not so much that I don't buy into IoC, but I don't buy into any kind of mentality that suggests there is only one way to do something (which is the prevalent attitude I sense from the IoC crowd).

In this simplified example above you switched from 3 lines of easily understandable code to something that requires code in the global.asax, another couple classes, and an interface. The end result contains an extra line or two of code, but now the whole thing is "reusable" and can be unit tested. I happen to agree with Joel's quote which you openly mocked... it *is* more convoluted. It *is* harder to read and grok. And this was an overly simple example... I'm sure it gets more convoluted with large projects.

That said, and I know it won't be popular in this crowd, lets change subjects a tad. Joel Spolsky says some dumb things every so often. We all know it. But you really need to stop harping about it. I can disagree with people about technical matters and still respect them, but when they attack other people's opinions...well, thats another thing entirely.
Neil Fenwick - October 9, 2009 - I like to simplify / make analogies to help understand:

So "Inversion of Control" is basically a Factory pattern fully implemented? As in "this is how it always should have been"...

I like this post and I'm sold on the benefits but was hoping you were going to illustrate how the ControllerFactory is implemented and uses Inversion of Control to provide an example :( Will have to try watch video later (easier to read in the office).

Overall - nicely written
Nicholas Piasecki - October 9, 2009 - Yeah, I've run into that post before, and I do really like the concept.

I guess for me it comes down to that it seems idiotic to build so much complicated ("something is more complicated than nothing") infrastructure in the initial release of a project, and then determining when it's time to "upgrade" the event-handling architecture of the codebase.

Still, even in such a domain events pattern, it seems to me that the IoC *container* ends up playing a small role, something that could be handled by a service locator or a factory. (Just changing the classes to that they will *work* with the container, by inverting the control, it seems, is 80% of the work in the exercise. And classes designed with inversion of control can have those dependencies satisfied by just about any scheme that I can dream up.)
Joshua Flanagan - October 9, 2009 - Yes, your IoC container lives at the "top" of your application (like in the controller factory), and preferably shouldn't be referenced anywhere else.
However, that does NOT mean you have an insane constructor party where the top class has to know about everyone else's dependencies. The container figures out how to build an object and all of its dependencies.
So if SillyController only directly uses INotificationSender, then that is the only constructor argument it has.
NotificationSender (the concrete implementation of INotificationSender) may have a constructor argument to take in IEmailTemplateProvider. The container will make sure that is satisfied too. SillyController doesn't need to know anything about IEmailTemplateProvider.
Joshua Flanagan - October 9, 2009 - I think it gets LESS convoluted with large projects. The "overhead" is more apparent on small samples like this, because of the relatively small amount of code to start with. In a larger project, the overhead of container configuration and call in global.asax is minimal (as it remains relatively static).
And with a larger project, if your code isn't written this way, you likely have a LOT more environmental dependencies that you need to set up every time you want to verify your code is doing what you think it is doing. In Rob's example, he only mentioned the hassle of having to make sure he had data in his database. You would also likely have to have application configuration just right, file system dependencies, windows services, SMTP servers, etc - just to verify your logic works as you think it does. It doesn't have to be that hard.
Ryan Roberts - October 9, 2009 - This is a pretty common reaction. Object oriented programming involves objects, designs that move from a procedural modules and records style to using stricter object oriented principles will have more objects.

"Resuse" isn't so much the issue as testability and maintainability (assuming that you don't have an a team / b team maintenance process). The high levels of decoupling you get using Real™ OO can make incremental changes to a code base less likely to affect half the system. That comes at a cost; the flow of how you got to this method with these dependencies harder to see, as you haven't just done it yourself procedurally. The method itself is likely to be far simpler though.

>I’m sure it gets more convoluted with large projects.

Convention based autowiring of services can simplify your work, at the price of requiring some general knowledge about the particular conventions you are using. Having type name / namespace based conventions can save a lot of code as well as help things stay neat and tidy. The service lifetime management features of containers can also be a godsend. Any service I ask for in a web request with autofac (that isn't registered as a singleton) is automatically disposed at the end of the request. Most containers also support pretty powerful component features that allow you to register a configurable set of services. Application start up routines are far more pleasant when they are mainly a bit of module discovery.
Adam - October 9, 2009 - Rob,

Good job on writing an introduction to IoC/DI. I got a good laugh at your reposes to Joel's comments.

I find it ironic that Joel thinks that people who use IoC lack empathy towards the common user. He has repeatedly demonstrated this same lack of empathy, when he talks about writing his own custom compiler as if it were a hello-world application.

Adam
Joshua Flanagan - October 9, 2009 - The ControllerFactory is pretty simple. Here is an example from an open source project:
http://code.google.com/p/mvbalaw-commons/source/browse/trunk/NHibernateBootstrap/src/NHibernateBootstrap.Web/StructureMapControllerFactory.cs?spec=svn35&r=35#

Once you have that class, you wire it up in your application_start of global.asax:
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
Smith - October 9, 2009 - Is there a typo in the following line of code
public PostRepository(IPostRepository postRepository){
should be
public PostController(IPostRepository postRepository){
Ryan Roberts - October 9, 2009 - >Still, even in such a domain events pattern, it seems to me that the IoC *container* ends up playing a small role

In my usage of it there's a per-request registry that pulls handler instances out of the container that register themselves as domain event handlers in their constructor. So the container is used for discovery of IHandleMessagesAbout and auto disposal / de-registration at the end of the request. It's not much infrastructure, but it is more than none. I have some multi tenant features that really need the decoupling.
Nicholas Piasecki - October 9, 2009 - Right-o, the issue I was having trouble understanding was what to do when the controller determined during its processing that it needed to create an object that had such a dependency (for example, NHibernate builds up a set of objects from the database after the IoC has instantiated the controller, and *these* objects have some sort of dependency). Domain events, as Ryan Roberts suggested, is one way around this, by effectively saying "don't do that." Understandably, it's unrealistic to expect the container to be able to instantiate every necessary object at the beginning of the request and hit "Play" as if it were running a simulation; some objects are going to be coming from different data stores or Web services during the actual processing of the request.
Dejan - October 9, 2009 - Look Rob, I’m really happy for you, I'mma let you finish, but Spolsky had the best IoC info of all time! :)

on a more serious note, nice post, thanks!
KevDog - October 9, 2009 - First, thanks for the very quick and simple IoC intro. Very cool.

Second, is it just me or is there a higher incidence of references to illegal substances in your writing since your departure from Microsoft?
Too Tall Aaron - October 9, 2009 - Rob,

I am trying to convince myself that you spend weeks or even months working on one article and that after 1,000 revisions you finally come up with what you write on your blogs. I am doing this because if you are able to explain topics, such as this IoC article, in the clear and humorous ways that you do without the agony that I envision then I have some self esteem issues to address. As someone who has tried countless times to explain & debate concepts such as IoC and TDD to programming squares I appreciate what you are able to pull off in your articles.

Keep up the good work!
Adam Wolf - October 9, 2009 - http://adamjwolf.com/post/2009/01/Castle-Windsors-MVP-and-AspNet.aspx

The easiest way for me to learn a new developing concept is by stepping through a good sample solution line by line. So, to help out, I have created a web application called “Simple CRM.” This application has one screen that only allows you to search for employees by name. The associated code contains everything you will need to get the project up and running. The web solution is configured to run on the built-in Asp.Net web server and uses a SQL compact edition database. Just download the code and hit F5 in Visual Studio.
Bruno Alexandre - October 9, 2009 - Hi Rob,

as this is my first post ever (here, but we changed messages on StackOverflow) I must say that I do love your blog and I wish I'll became a great developer like yourself ... and for that I would suggest something ...

I like tutorials, I love posts and I tend to do all as I can, but sometimes I'm stuck in really easy stuff cause I loose myself on all the letters... I am a great fan of screen casts, and for this I would suggest that u could post a poll just to see how many of us loved to have a less than 5 minutes (maybe using JING) area in this blog ... not for all stuff, but I do thing it's much easier to record something and doing it live than copy/paste images and create a how-to tutorial like you present us several times ....

what do u think? and ... what do you readers like me think?

keep your fingers tickling on that keyboard ;)
Too Tall Aaron - October 9, 2009 - I agree with you Bruno! There are A LOT of REALLY smart developers in the world. A TON. There are A LOT of REALLY creative people who can write interesting and informative articles in the world. A TON. There are SO FEW smart developers who can write interesting and informative articles. A FEW. Rob is one of them.

Hey Rob... you have been nominated... We know you are an ace with screencasts (Kona has proved that). We know you can knock out a blog article in "just over an hour". Get crackin' with the screencasts of your blog project!
S1n - October 9, 2009 - Thank you Rob for explaining IoC and DI simply and to the point. I even (even I) understand it. Can you explain the infield fly rule next?
NotMyself - October 9, 2009 - "people who use IoC containers are lacking in empathy for people who aren’t as smart as they are are to lazy to read a blog post or two and create a sample application to experiment with."
Trevor de Koekkoek - October 9, 2009 - Great article. Only first when I read it through my feed reader, the quotes didn't show up around Spolsky's comments.
I thought could Rob actually be saying these things? Anyway, about the only thing I sort of concur with Spolsky is that
some of the IOC providers make it seem complicated. When I first looked at StructureMap I didn't really know what an IOC was
and I had a heck of a time finding any "getting started" documentation. About a year later I looked again and found 3 or 4
different ways of doing the configuration and none of it worked for me. Then I tried Unity and had it working in a few
minutes. So no it isn't rocket science but sometimes not well explained. At least you've filled that gap now.
John - October 9, 2009 - Rob, I love you man, but I'm sensing some negativity. Time to take a nice long walk and enjoy the beautiful sunshine -- somebody living in paradise shouldn't be quite so negative.

Also, here's the Fowler article. When in doubt, it's almost always a good idea to see what Martin says. http://martinfowler.com/articles/injection.html
Zach - October 9, 2009 - "Typically what you might do, as a developer, is to hit F5 (Debug/Run) to see if data appears on your page. It’s still magic to me after all these years to see data from my DB hit the screen – I dig that rush and for a moment my little itch is scratched and I feel good about myself. I see data there – so it works."

I find that hilarious and true! No matter how many times you hit F5, its is amazing to see DB data on the screen!!!
freddy - October 9, 2009 - While its not possible, you can use Property injection (careful, the cool kids might scream :P). See what I posted here: http://stackoverflow.com/questions/514638/presenter-injection-in-model-view-presenter-pattern-with-structuremap/548723#548723
freddy - October 9, 2009 - You don't need to pass the internal dependencies from the top. This is a place where having the IOC shines vs. doing it yourself.

Say, SomeController depends on ISomeStuff. And a particular implementation of ISomeStuff uses an IMailer. So, you have in SomeController:

ISomeStuff _someStuff;
public SomeController(ISomeStuff someStuff) {
_someStuff = someStuff;
}

Notice there is no mention of the IMailer. In the SomeSpecificStuff you have:

IMailer _mailer;
public SomeSpecificStuff(IMailer mailer) {
_mailer = mailer;
}

And the structure map config:

ForRequestedType()
.TheDefaultIsConcreteType();
ForRequestedType()
.TheDefaultIsConcreteType();
freddy - October 9, 2009 - the blog ate the type arguments ... suffice it to say those config lines where ISomeStuff - SomeSpecificStuff ... and the other IMailer - SmtpMailer.
freddy - October 9, 2009 - You are right, if you get these instances of objects built from external systems with info retrieved when running the logic, its not as simple to think about it as presented here. This conflicts to what I just said in other comment, but hang with me.

Basically it is simple to build complex systems If you do it this way from the start / or early on.

If you have invested a lot in having all these different functionalities baked into those classes and all is tied in with through static classes / factories, introducing something like this is Hard. The same happens when you try to do unit tests, and its why you can pull your hairs and say its not worth it and never want to see unit tests again.

The issue with the above is that everything is coupled. Now loose coupling / high cohesion is not a new concept, its just that its hard to get what it really mean and how to really achieve it. Nowadays there is plenty of info floating around on how to achieve it and explaining so many different factors of it in much simpler ways.

Even if you use a factory to give u the dependency in a neutral way, like Mailers.Current, it still ties your code to that as u need to work around it when u want to test it to be able to get stuff in there. It also makes it harder to know what a given class depends on - because dependencies are mixed inside the code.
Oralc - October 9, 2009 - Why is DI for people who don't know math?
bennyb - October 9, 2009 - Shouldn't the final piece be:


public PostRepository(){

}

public ActionResult Index(){
var repo=ObjectFactory.GetInstance();
var posts=repo.GetPosts();
return View(posts);
}
Thiru - October 9, 2009 - Great post Rob! I've had Martin Fowler's DI & IOC post in my to-read list for a while now and haven't gotten through it. I'm glad Joel was there once again to light your fire.

Don't you think it's good to have someone on the other side of the fence who's very intelligent and often makes interesting observations? Obviously (to me, you and most at least) in this case he was wrong. But in may other instances it's not so clear. And for that reason he is still very well worth paying attention to :).
Thiru - October 9, 2009 - Yep, looks like it. Rob can you make the fix?
Chance - October 9, 2009 - Rob - you left out a part of IoC which I've always thought was awesome.

In many IoC, you can setup the mappings in XML. How does this help you ask? Well, what if you have several servers (dev, staging, prod), you simply swap out your config file and go on your merry little way.
Avery - October 9, 2009 - Nice read. Thanks very much for the clear explanation.

Too bad it took 5 months to condense that 200 page manual and respond to Joel's post from May 16th ;)
Jason - October 9, 2009 - Decent article, but your elitist intro is insulting to your readers and just makes you sound like a Jackass.
Rob Conery - October 9, 2009 - Who says geeks don't have a sense of humor? I am a jackass btw...
Rob Conery - October 9, 2009 - This is from a Stack Overflow comment of his made this week.
Rob Conery - October 9, 2009 - No - the fun thing here is that if you override the ControllerFactory, all injection is done at that point :) so you don't need this all over your code. I'll writeup a follow up tomorrow...
Rob Conery - October 9, 2009 - Actually I should explain more - the intro was in reference to Joel's assertion that you need a "big brain" to understand IoC. Sometimes my jokes are a bit too dry - I'd never say something like that in seriousness :). Most readers of my blog understand I have a fairly "dry" sense of humor, but when posts like this land on Digg or Reddit people don't tend to see my "humor".

Anyway - please read that as sarcasm :)
Benjamin Robbins - October 9, 2009 - Rob,
I agree and disagree with you on this topic.

This is the newbie's guide that I could have used a year ago. As an adult student programmer who's been coding for about two years now, I was first truly introduced to IoC and DI from your storefront video with Jeremy Miller. It looked really cool and useful, but it was somewhat complicated to figure it out at the time because finding relevant and up-to-date Asp.net MVC and StructureMap information wasn't as straight forward as it is now. I did blunder around for a bit and get it figured out and integrated into my asp.net mvc app, but there was a cost of learning that I had to pay. With that cost paid, I can leverage my knowledge to apply to any of the handful of IoC containers that are available, but the initial cost cannot be ignored. As you start getting into some of the more complicated use-cases for your IoC container of choice, then you are paying the cost of learning again. However, you typically won't need the complicated usages to get started, so that learning cost can be delayed until it's necessary to pay it. Spolsky alluded to the learning cost as the curse of knowledge article link. The Cool Kids have paid this cost, and cannot empathize with people who haven't yet paid this cost. This lack of empathy caused the massive backlash and internet drama that led us here.

Spolsky makes valid points and never says that IoC is bad, and he answers the question that is asked: "What do I gain using someone else's IoC framework compared to the manual DI that I'm currently using? Is it worthwhile to train my possibly resistant coworkers to use the framework?" Instead of paying attention to that, you focus on the fact that Joel references this hypothetical 200 page manual.

I ran across this post on devlicious regarding the Spolsky kerfuffle: http://devlicio.us/blogs/vinull/archive/2009/10/08/critical-thinking-and-dissent-is-a-requirement.aspx . Spolsky bashing has become an unwritten tenet of the alt.net (AKA the Cool Kids) dogma, and I find it quite distasteful. I find the Cool Kids to be a valuable font of information as I also find Joel Spolsky to be a valuable font of information. It's my duty to myself to sort the relevant and useful information from the less useful information. It's a more important duty to myself not to waste energy focusing on the irrelevant information. This guide is the result of you focusing on a leaf instead of the forest, but it is still very valuable if you take out any reference to Spolsky and simply treat it as the newb's easy start guide to using an IoC framework.
Roger Pence - October 9, 2009 - Great post. Thank you, Rob. I'm digging the cool kid side of the street.
jim d - October 9, 2009 - Agreed, and for all of Joel's supposed faults I don't think it's often where he specifically calls people out and insults them.
Mohamed Meligy - October 9, 2009 - Rob, Brilliant as usual!

Waiting for the part 2: "Di/IoC Frameworks, Or, are you a poor man?" :D
jim d - October 9, 2009 - Rob,

It's unintentionally hilarious that you paired Spolsky's "200 page" quote with your usage of StructureMap. The training guide (not including the "Quick Start" or "Glossary") is 80 pages and the API clocks in at around 215 pages. Go to http://structuremap.sourceforge.net and see for yourself.

That said, I do like IoC. I just think the community has a tendency of turning things into an overwrought mess.
Cohen - October 9, 2009 - Actually I like the blog posts more. I can read them diagonally and pick out the interesting parts for me.
With screencasts this is not possible, I hardly ever watch any bacause of this. I'll have to sit through the whole thing.
Cohen - October 9, 2009 - Rob,
Loved how you lined up the benefits of IOC/DI in a readable compact way.
I'm gonna use some of it when I'll be explaining these concepts next week to a dev team. :)

Although I agree with all the great points about IOC/DI and I know it's addictive to use (The code is so much cleaner, and all dependencies are explicitly documented through the code, I've seen a lot of developers struggle with the added abstraction. So like everything in live, we should find a middle ground (I am not sure if you say it like that in english, though).
Areg Sarkissian - October 9, 2009 - One thing that I have found that somewhat complictates the use of DI/IOC container is when you have a construct like this that you want to convert to use DI:

using (IDataAccess dal = new SqlDataAccess(Configuration.ConnectionString) )
{
...//Do data access stuff
}//at this point dal.Dispose() is called immediatly closing connection to Database

Make sure the DI container calls dispose on IDataAccess or Close the connection manually after your done by calling dal.Close() to close the connection immediatly if there is a lot more stuff to do in the web request before it complets. The DI will call Dispose only when the request ends. Assuming you configure the DI container for per web request thread lifetime management.
I find that handling the lifetime management issues seem to be the area that adds a little bit of complexity to DI frameworks
Areg Sarkissian - October 9, 2009 - Just wanted to add that when you convert to using a DI container you can not use the "using" construct any longer
since the IDataAccess instance will now be managed by the container.
Cohen - October 9, 2009 - I personally think that things like IOC/DI emerge because people in some situation find that "there is a better way"

It is something you grow into. If you think it adds a lot of code that isn't worth it you're probably not ready yet to use a IOC/DI container.

If you've never used factories and service-locator's, you'll probably not appreciate the problems a IOC/DI container solves. (And I am not even touching object lifetime or lifestyle management)

The first project I used IOC/DI in I had to take the time to educate the team how things worked. It does add an extra layer of abstraction, and people who don't know IOC/DI will find it a lot harder to read (where and who provides the implementation for this interface I am using?).
In projects I found that:
- it clearly documents the dependencies between the classes (just look at a constructor)
- makes you think about the separation of concerns and dependencies which results in better,maintainable code from the start.
- requires you to write loosely coupled (we are almost always writing against interfaces)
- ...
Cohen - October 9, 2009 - we went from service locator to IoC
- it documents the dependencies in a single place (parameters of the constructor)
- gives you validation (StructureMap can check if all dependencies are met)
- the statements to get a certain component/service aren't scattered all over the place.
- provides better isolation (consistency) from IoC/DI container configuration changes during runtime.

But I have to agree that service locator's are easier to read and more transparent especially if you're starting IOC/DI. They look a lot like the factory pattern, which is well known.
Joshua Flanagan - October 9, 2009 - Actually, he made the comment back in May. But I stumbled upon it this week when I was answering StructureMap questions on SO. I got so mad about it that I was still ranting when I got into work. Chad twittered it, and the community "corrected" it, just as things are supposed to work on SO. Unfortunately, it sat out there for 5 months as the top voted, accepted answer, corrupting untold numbers of minds...
design - October 10, 2009 - > its all about testability. But DI doesnt increase testability. Thats a myth. The time and effort to set up mocks is even higher than for simpler and better alternatives.
Paul Hammant - October 10, 2009 - Nice working pushing the IoC and DI cause. Nicer still if you could briefly explain the difference between IoC and DI to your readers. Or at least the fact that IoC includes ideas about lifecycle & configuration.

Lastly, StructureMap has a VERY un-IoC feature which you promote it in your 1-page article. Namely ObjectFactory has a static accessor for components. IoC is supposed to eliminate such ideas not encourage them.

- Paul Hammant
( one of the reviewers for Fowler's article, and co-author of the first Constructor Injector DI container - PicoContainer )
razvan dimescu - October 10, 2009 - cool article. DI + IOC = GG
Liam McLennan - October 10, 2009 - IoC and service locator both achieve the same thing, and a both valid. IoC is currently more popular but if a service locator works for you then use that.
Vukoje - October 11, 2009 - Hi Rob,

I am following your blog for some time and this is a first time that I strongly disagree with you. Yes you are smart and cool, but from bussines perspective you are insane programmer who needs someone to manage him.

So you needed to remove dependancy form DB, you create you interface to introduce low coupling. Now you need your controller to use another repository and usually only in one test class because it is Unit Test. So I use setup method that in one line code with reflection sets a Stub repository class to conroller. You introduce bunch of new concepts and external libraries.

As I see it your approach is more cool and geek in me is crying out to use it, but my is way simpler. You have avoided technical debt only if you ignore increased complexity.

Another thing, yes IoC is super cooland currently heap, but may I remind you that we are professionals, not kids.
David Miller - October 11, 2009 - I've been trying to look at ways of achieving this for a couple of weeks now.

Would a pre-JIT approach like this even be possible against the System.Web.HttpRuntime.CreateNonPublicInstance() method calls?

http://www.codeproject.com/KB/dotnet/CLRMethodInjection.aspx

I've used PostSharp.Core to replace my new Object() calls with ServiceLocator.GetInstance in libraries that I control, but never found an effective way of messing with other peoples assemblies.
Daniel - October 11, 2009 - My humble opinion is... If you are a professional developer (you're being paid for your services) and you can't understand DI or IoC after reading a simple article (like this one), you really should consider yourself outdated and you should be lucky if you get to work with any Green field projects.

//Daniel
Rob Conery - October 11, 2009 - It would be great if you could manage me because clearly my career has faltered to this point :).

>>So I use setup method that in one line code with reflection sets a Stub repository class to conroller
Not sure if you read the post, but this is IoC. The difference is that, as your boss, I just paid you to write this versus you taking off the hard hat and seeing that others have done this already (and thought through all the myriad problems you're about to face).

>>You have avoided technical debt only if you ignore increased complexity.
Technical debt is about "not leaving something for later". Usually that involves dealing with complex issues up front - so in that you have this exactly backwards.

>>but may I remind you that we are professionals, not kids
Go to your room :)
Rob Conery - October 11, 2009 - The difference (for me) RE the Spolsky thing is when he asserts people (you) aren't smart enough to understand IoC. That deserves a bit of a slap as it's rather elitest don't you think?

His points RE the framework's complexity and lack of docs are indeed valid - and I think he was going there - but as all weak positions do he decided to generalize his point to all of IoC.

I do agree that really smart dudes wrote the containers - but the core concept is bleedingly simple.
Rob Conery - October 11, 2009 - Doh! I never looked at the date - you're right! How did I miss that...
Anne Epstein - October 11, 2009 - Looking back on my learning of IoC, the tough part wasn't seeing the idea of injecting a dependency, it was learning to correspondingly invert the way I thought about structuring code. At first, I didn't understand where this odd, complicated IoC idea fit with the way I worked with code. Over time, I understood-it's great when used *everywhere*... and in fact, from that new perspective, IoC wasn't even complicated, it was actually an enabler of simplicity-instead, the old way of hardcoding dependencies seemed awkward. Unfortunately, I think it's easy to confuse unfamiliarity with true complexity, and you really don't have the information to distinguish the two until you've already gotten over the familiarity hump.
hilton smith - October 11, 2009 - yet another reason the internet needs a sarcasm font...
seriously
Vukoje - October 12, 2009 - First to be clear, you are excellent programmer, much better than me... yes I am serious :)

>>>>>>So I use setup method that in one line code with reflection sets a Stub repository class to conroller
>>>>Not sure if you read the post, but this is IoC. The difference is that, as your boss, I just paid you to write this versus you taking off the hard hat and seeing that others have done this already (and thought through all the myriad problems you’re about to face).
>>No Rob, I have no problem, I had a problem with mocking in tests and I solved it with one line of code per test class. If you don't like reflection, you can use internal properties and friendly assemblies.

>>>>>>You have avoided technical debt only if you ignore increased complexity.
>>>>Technical debt is about “not leaving something for later”. Usually that involves dealing with complex issues up front – so in that you have this exactly backwards.
>> Yes Rob, but dealing with needed (oblogated, required) complexity, not adding your own. In your solution your whole application (again... whole application! that's all code) has dependency on external component. Are you sure that there is no risk here?

And finally and most importantly, how did all of you managed to break very basic OOD principle - encapsulation and not feel guilty. Once you had PostController with simple and logical API and now you have constructor that accepts Db Broker and who knows what else.

After all said, IoC is very interesting concept, but...
I will quote Facts and Fallacies of Software Engineering:

* Hype (about tools and technology) is a plague on the house of software.
* New tools and techniques cause an initial loss of productivity / quality.
* COBOL is a very bad language, but all the others are so much worse.
Rob Conery - October 12, 2009 - Thanks for the comment - I'm not sure if you're open to the whole thing but I did write a follow up to show you (and others) the "why" here.

IoC has nothing to do with testing - so I'm not too sure what your point is there. DI does - and that's a very old pattern.

Take a look at the code - the Controller is perfectly encapsulated, much moreso than having a "databroker" inside of it. Your idea of a "simple API" is, once again, backwards to what you're proposing: encapsulation.

Quoting things is Appeal to Authority - a fallacy in itself. This isn't hype, it's just mean explaining a tool. It's not new by any stretch - it's just not widely used.

I might offer you are typifying the stereotype here - making judgements about something you haven't tried, offering an attack on *me* versus my points (which is OK - I don't take it personally). And do me a favory - don't backtrack on this, you started off telling me I was hard to manage :) and then led into some fairly direct points.

This is OK - but now it's your turn: you need to stop making knee-jerk assessments of something you clearly know nothing about. It makes you look like a fool because when you try this very "Green Eggs and Ham" concept you will smack yourself for leaving this comment before you truly tried it.

--Sam I am.
Otmar Pereira - October 12, 2009 - I think IoC is very useful, and nowadays i tell people they have correctly layered their systems if they use a pattern similar to this. But one thing i don't like is the dependecy resolution done in code. I think that if I can set all the dependencies resolutions in a configuration file, I'm in a much better situation, because even a new compilation is necessary! Just update the config file and drop a DLL that contains the concrete type and you're done! Can anyone see any con of this approach?
Gecko