views:

2115

answers:

3

Derik Whitaker posted an article a couple of days ago that hit a point that I've been curious about for some time: should business logic exist in controllers?

So far all the ASP.NET MVC demos I've seen put repository access and business logic in the controller. Some even throw validation in there as well. This results in fairly large, bloated controllers. Is this really the way to use the MVC framework? It seems that this is just going to end up with a lot of duplicated code and logic spread out across different controllers.

+11  A: 

Business logic should really be in the model. You should be aiming for fat models, skinny controllers.

For example, instead of having:

public interface IOrderService{
    int CalculateTotal(Order order);
}

I would rather have:

public class Order{
    int CalculateTotal(ITaxService service){...}        
}

This assumes that tax is calculate by an external service, and requires your model to know about interfaces to your external services.

This would make your controller look something like:

public class OrdersController{
    public OrdersController(ITaxService taxService, IOrdersRepository ordersRepository){...}

    public void Show(int id){
        ViewData["OrderTotal"] = ordersRepository.LoadOrder(id).CalculateTotal(taxService);
    }
}

Or something like that.

jonnii
So would you inject Services into your controllers instead of repositories then? How does the Unit of Work principle come into play in that case?
Kevin Pang
I wrote some more stuff, I hope this makes more sense.You might want to also read:http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-modelEven though it's about Rails it's still very much applicable.
jonnii
I would call a repository a service, personally.
Brad Wilson
They're definitely a kind of service, but are specifically for data access. It's just a convention I use, not something I advocate specifically.
jonnii
I agree with the answer.
David Leon
@kevin pang- sorry what's the unit of work pricincipal?
Maslow
A: 

This is a fascinating question.

I think that its interesting that a large number of sample MVC applications in just about any framework fail to actually fail to follow the MVC paradigm in the sense of truly placing the "business logic" entirely in the model. Martin Fowler has pointed out that MVC is not a pattern in the sense of the Gang Of Four. Rather, it is paradigm that the programmer must add patterns to if they are creating something beyond a toy app.

So, the short answer is that "business logic" should indeed not live in the controller, since the controller has the added function of dealing with the view and user interactions and we want to create objects with only one purpose.

A longer answer is that you need to put some thought into the design of your model layer before just moving logic from controller to model. Perhaps you can handle all of app logic using REST, in which case the model's design should be fairly clear. If not, you should know what approach you are going to use to keep your model from becoming bloated.

Joe Soul-bringer
+1  A: 

Take a look at my blog post about ASP.NET MVC Controller Best Practices and skinny controllers where I address this issue.

Jag Reehal