How to reduce the number of entered dependencies on the controller

I am using MVC3, Entity Framework v4.3 Code First and SimpleInjector. I have a few simple classes that look like this:

public class SomeThing { public int Id { get; set; } public string Name { get; set; } } 

I have another object that looks like this:

 public class MainClass { public int Id { get; set; } public string Name { get; set; } public virtual AThing AThingy { get; set; } public virtual BThing BThingy { get; set; } public virtual CThing CThingy { get; set; } public virtual DThing DThingy { get; set; } public virtual EThing EThingy { get; set; } } 

Each Thingy (currently) has its own Manager class, for example:

 public class SomeThingManager { private readonly IMyRepository<SomeThing> MyRepository; public SomeThingManager(IMyRepository<SomeThing> myRepository) { MyRepository = myRepository; } } 

Therefore, My MainController follows:

 public class MainController { private readonly IMainManager MainManager; private readonly IAThingManager AThingManager; private readonly IBThingManager BThingManager; private readonly ICThingManager CThingManager; private readonly IDThingManager DThingManager; private readonly IEThingManager EThingManager; public MainController(IMainManager mainManager, IAThingManager aThingManager, IBThingManager bThingManager, ICThingManager cThingManager, IDThingManager dThingManager, IEThingManager eThingManager) { MainManager = mainManager; AThingManager = aThingManager; BThingManager = bThingManager; CThingManager = cThingManager; DThingManager = dThingManager; EThingManager = eThingManager; } ...various ActionMethods... } 

In fact, this controller has twice as many nested dependencies. It smells. The smell is worse when you also know that there is OtherController with all or most of the same dependencies. I want to reorganize it.

I already know enough about DI to know that property nesting and a service locator are not good ideas.

I cannot share my MainController because this is the only screen that requires all these things to be displayed and edited with the click of a Save button. In other words, one post-action method saves everything (although I am open to change if it makes sense, if only it remains with one Save button). This screen is built using Knockoutjs and saves Ajax messages, if that matters.

I enjoyed using the Ambient context, but I'm not sure if this is the right way. I enjoyed using the Facade injection. I am also wondering if I should implement the Command architecture at this point. (Not all of the above just move the smell somewhere else?)

Finally, and perhaps regardless of the three above approaches, should I instead have one, say, LookupManager with explicit methods such as GetAThings (), GetAThing (id), GetBThings (), GetBThing (id), etc. .? (But then this LookupManager will need several repositories attached to it or a new type of repository.)

My thoughts aside, my question is to repeat: what is a good way to reorganize this code to reduce the crazy number of nested dependencies?

+7
source share
3 answers

Using a command architecture is a good idea, as it removes all business logic from the controller and allows you to add cross-cutting problems without changing the code. However, this will not solve your over-injection constructor problem. The standard solution is to move related dependencies to the aggregated service . However, I agree with Mark that you should take a look at the work template block .

+3
source

Have you considered using the unit design pattern? There is an excellent MSDN publication on what a unit of work is. Excerpt from this article:

In a sense, you can think of Unit of Work as the place where you need to reset all transaction processing code. Responsibilities of the Labor Group for:

  • Transaction management.
  • Order database insertions, deletions, and updates.
  • Prevention of duplication of updates. Within one use of the Unit of Work object, different parts of the code may mark the same invoice, the object has changed, but the Unit of Work class will issue only one UPDATE command to the database.

The value of using the Unit of Work template is to free the rest of your code from these problems so that you can concentrate on business logic.

There are a few blog posts about this, but the best I have found is how to implement it here . There are others that have been mentioned on this site here and here .

Finally, and perhaps regardless of the three above approaches, should I instead have one, say, LookupManager with explicit ones such as GetAThings (), GetAThing (id), GetBThings (), GetBThing (id), and so on? (But then LookupManager will need a few repositories attached to it or a new type of repository.)

A unit of work will be able to handle all of these functions, especially if you can implement a common repository for most database processing tasks. Does your tag mention that you are using Entity Framework 4.3 correctly?

Hope this helps!

+4
source

I think your main problem is too many levels of abstraction. You are using the Entity Framework, so you already have an abstraction layer around your data, adding two more layers (one per object) through the repository, and the manager interface has led to a large number of interfaces on which your controller depends. This does not add much value, and, in addition, YAGNI .

I would reorganize, get rid of your repository and manager layers and use the "surrounding context".

Then look at the types of requests that your controller requests from managers. Where it is very simple, I see no problem with requesting your "surrounding context" directly in your controller - this is what I would do. Where they are more complex, reorganize it into a new interface, logically grouping things (not necessarily one at a time on Entity) and use IOC for this.

0
source

All Articles