3

I recently started reading about ASP.net MVC and after getting excited about the concept, i started to migrate all my webform project to MVC but i am having a hard time keeping my controller skinny even after following all the good advices out there (or maybe i just don't get it ... ). The website i deal with has Articles, Videos, Quotes ... and each of these entities have categories, comments, images that can be associated with it. I am using Linq to sql for database operations and for each of these Entities, i have a Repository, and for each repository, i create a service to be used in the controller.

so i have -

  • ArticleRepository
  • ArticleCategoryRepository
  • ArticleCommentRepository

and the corresponding service

  • ArticleService
  • ArticleCategoryService ...

you see the picture.

The problem i have is that i have one controller for article,category and comment because i thought that having ArticleController handle all of that might make sense, but now i have to pass all of the services needed to the Controller constructor. So i would like to know what it is that i am doing wrong. Are my services not designed properly? should i create Bigger service to encapsulate smaller services and use them in my controller? or should i have an articleCategory Controller and an articleComment Controller?

A page viewed by the user is made of all of that, thee article to be viewed,the comments associated with it, a listing of the categories to witch it applies ... how can i efficiently break down the controller to keep it "skinny" and solve my headache?

Thank you! I hope my question is not too long to be read ...

ak3nat0n
  • 4,971
  • 6
  • 34
  • 56
  • My controllers currently have 6-10+ dependencies which I pass to the constructor. This also results in bulky controllers but that's just because I'm often showing a lot of data from different sources within a single page and all of that data has to be loaded up into the view model. – Todd Smith Mar 24 '10 at 18:39

2 Answers2

7

This is the side effect of following the Single Responsibility Pattern. If each class is designed for only one purpose, then you're going to end up with a lot of classes. This is a good thing. Don't be afraid of it. It will make your life a lot easier in the long run when it comes to swapping out components as well as debugging which components of your system aren't working.

Personally, I prefer putting more of my domain logic in the actual domain entities (e.g. article.AddComment(comment) instead of articleCommentService.AddComment(article, comment)), but your approach is perfectly fine as well.

Kevin Pang
  • 39,694
  • 37
  • 117
  • 169
  • if i display an article with its related categories-comments-images,do i have to put them all in one single controller for it to work? How to deal with such complex object as an article? I feel like using your approach (categories and comments are part of the article domain) might help me solve the problem while taking me away from the SRP ... – ak3nat0n Mar 23 '10 at 21:14
  • I would have an Article class that had properties for its Categories, Comments, Images, etc. These would be lazy-loaded so as to not require me to fetch the entire object graph from DB when I may only just need the Article metadata. Does that answer your question? I'm not sure I understand how this breaks SRP. SRP doesn't mean related entities can't reference each other. – Kevin Pang Mar 23 '10 at 21:17
  • You are right they can reference each other , i didn't think about it that way. thank you! – ak3nat0n Mar 23 '10 at 21:28
2

I think you are headed in the right direction. The question is how to instantiate your services? I'm no MVC.NET guru, but have done plenty of service oriented Java projects and exactly the pattern you are discussing.

In Java land we would usually use Spring to inject singleton beans.

1) You can do the same thing in .NET, using dependency injection frameworks.

2) You can instantiate services as needed in the method, if they are lightweight enough.

3) You can create static service members in each controller as long as you write them to be threadsafe, to reduce object churn. This is the approach I use in many cases.

4) You can even create a simple, global service factory that all controllers access, which could simply be a class of singletons.

Do some Googling on .NET dependency injection as well.

codenheim
  • 19,092
  • 1
  • 51
  • 77