Dependency Injection into Controller Actions in ASP.NET MVC

 

Dependency Injection into Controller Actions in ASP.NET MVC

Where I work, we use Siege for all of our new (and most of our existing) web applications, taking advantage of it’s contextual resolution capabilities to focus on programming our applications and less on making them compatible with our container by generating types and interfaces specifically for distinction by the container. One of the things that we came to realize was that for several of our controllers, the constructor dependencies were growing a little out of hand.

The problem is that for some of our dependencies, they are really only used in one controller action. It turned out that while there were a few core dependencies shared throughout our controller, there were also a lot of one-off dependencies that were being injected to the constructor for specific actions. 

 

Injecting Directly into the Action

In some cases, the answer was to decompose the controller so as to separate out the dependencies a little better. However, in many instances, it made sense to leave the controller together, but to move the dependency from the constructor to the action method. We accomplished this through a minor extension to Siege’s asp.net mvc integration library, which was very simple to do. If you’re using Siege and the ASP.NET MVC integration library, it’s very simple — just update to the latest version and start adding injectable dependencies to your controller actions like so:

 

public ActionResult Foo(IBarService service)
{
   //put your code here 
}

 

If you’re not currently using Siege, but want to start — just go to the Download Page and get Siege.Requisitions.Web and one of the adapters (if you aren’t using an IoC but want to start, I suggest the SiegeAdapter!)

Then, in your global.asax.cs file, simply inherit your GlobalApplication from ServiceLocatorHttpApplication et voila! You should be good to go.

 

But wait, there’s more!

Straight dependency injection into controller actions is nice, but Siege.Requisitions actually enables you to conditionally inject implementations based on behavior from the user. In one of our scenarios where I work, we integrate with multiple vendors and in some of our administrative applications, users choose vendors to send information to by selecting specific options from a drop down. Not only are we able to inject the dependency directly into the controller action, but we are additionally able to have our container automatically pick an implementation by understanding which selection the user has chosen on the form.

This all happens automatically, without any need for the developer to write controller code to resolve anything, or any code really, other than expressing this through additional registrations. How does that work, and what does it look like? I’ll cover that in the next post, which is all about Contextual Awareness: How the Container infers your intent by observing the system.

Siege Download Page
Siege on GitHub
Follow me on Twitter for Siege updates 

 

Happy Coding!

 

Related Articles:

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

This entry was posted in IoC, MVC, Siege. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.lostechies.com/members/derick.bailey/default.aspx derick.bailey

    interesting approach. i can see how the contextual resolution on the dependencies is a big benefit, here.

    i have some questions and concerns, though…

    are you worried about the overall design of the controllers when you have to start injecting dependencies into the individual action methods? it seems like a violation of a lot of the principles we espouse… encapsulation being the main one.

    how does your team get a sense of the larger requirements when the logic of which implementation to use is baked into the IoC registration instead of the application itself? does this knowledge get lost? does it get confusing in to have to jump between the controller and the registration just to see if you need to look at the registration to understand what the possible implementations are?

    have you explored any of the ‘controllerless action’ ideas? or has anyone really found a way to do that in asp.net mvc? I’ve been wanting to explore this idea for a while now. it seems that a class per action may be more appropriate in the cases where we find a controller becoming bloated. or perhaps, a Delegate per action, registered with a container…

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

    Hi Derick,

    As with any piece of technology, it’s available for abuse. The tool is only as efficient as the one yielding it. I’m not concerned on my team because we do actively review code and would catch things like this.

    We have a bigger problem I think with controllers with 10+ injected dependencies. In the end, it’s all down to judgement. I prefer to trust the judgement of the consumer and enable the functionality should they decide it’s necessary, rather than take it away from them and say, “I know better than you about what you should be doing.”

    With regard to jumping back and forth between code and registrations to see what’s going on — I see your point. I think in the end its down to the team to build the expertise about the system and the business domain to understand things. To me its very similar to auto-wiring all your dependencies. By the time you get to your controller, you have no way of seeing which type is registered. You have to go look at the registrations to see what conventions are being applied, and infer the information.

    To me, this is actually a little more straightforward … at least we have some sort of code stating what the rule and how the decision was made! :)

    So far we haven’t run into an issue where people couldn’t easily understand what was going on … but like I said earlier, if it were overabused or implemented in a wacky fashion, I could see the potential for trouble.

    Again, at some point I just have to trust to the judgement of the developer using the tool.

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

    I forgot to mention — I haven’t explored any controllerless action ideas in much detail. I’m familiar with it, and off the top of my head I can see where to hook in to do it, but I’m concerned about it becoming even more scattered and hard to decipher (and test!)

    If I wire everything into the container, then it becomes ServiceLocatorMVC :) What do you think?