C# – Best Practice: How to get several dependency repositories into a ActionController

asp.net-mvccdependency-injectionioc-container

I have a InventoryController that gets a IInventoryRepository inyected, however my needs have changed, and now one of the controllers methods also needs to use another 2 repositories, ILoansRepository (to see the get info about loaned inventory items) and another one, where some stats and extra info are found.

The way it works is that a ViewModelBuilder class that gets called from an ActionMethod in the InventoryController, that is the one that actually needs those. Currently I was passing the IInventoryRepository from the controller to the builder, but how should I do it now? Should I get the 3 repositories injected into the controller, and then pass them to the builder, just as I've been doing now? Or should I just do a IoC.GetInstance()? (although I think that is an anti-pattern isnt it?)

thanks!

Best Answer

In situations like these, the following guidelines come into play:

  • Too many dependencies is a smell that you violate the Single Responsibility Principle.
  • Don't have more than four dependencies. This is a relative guideline. I personally strive to have less; I get restless as soon as I add a third dependency (see the first item above), but can live with up to four. More than that and I have to refactor.
  • Don't take dependencies just to pass them on.

As far as I can tell, with three dependencies, you are still more or less within the safety zone when it comes to the number of dependencies, although you should start watching that particular design aspect more carefully.

However, as I understand your current implementation, you simply pass on the dependencies to a ViewModelBuilder (thus violating the third bullet). A slightly better option would be to define an abstraction of that (say, IViewModelBuilder) and inject that into the controller instead of all three repositories.

Under no circumstance should you resort to the Service Locator anti-pattern (IoC.GetInstance()).