Question

I am building an ASP.Net MVC web application using an n-tier approach. My structure looks like this:

Business Objects - Model
Data Access Layer - DAL
Business Logic Layer - BLL
Mapping Layer
ViewModels
Controllers
Views

I usually put calculations in the business layer, but what about calculations that are only used for presentation purposes? For example, on a view in my application I show the Invoice Total, any Payments made and the Balance Owing. Balance Owing is a calculated amount. Since I use Balance Owing many times in my application I am inclined to create a generic BalanceOwing method in my BLL, but there are other cases where a calculation is only ever going to be used for one view. In this case should the calculation instead go in the controller or in my case the mapping layer? (I have a mapping layer which I use to convert domain models to viewmodels. It keeps the controller tidier).

Is that really the dividing line? That is, if I can generalize a calculation and use it more than once it should go in the BLL, but if it is specific to one view it should be in the controller or mapper?

SUMMARY:

I went with @trailmax's answer because he saw that some things that I thought of as presentation logic were in fact business logic and therefore belong in the BLL. In cases where something really is presentation logic and involves calculations such as pagination, I would put these in a utility class or extension method as mentioned by @ramiramilu

Was it helpful?

Solution 2

It all comes down to what you consider to be a "view-specific". If that is a calculation of screen resolution or browser version - then absolutely. If you are talking about duration that is simple enough, I'd think twice. It might look simple, but actually in the future can evolve - just keep it in BLL.

In comments you mentioned period duration. This might look simple just now (End - Start).Date. But this might evolve later into calculate the duration of this period excluding Weekends (for example). And this is definitely BLL, not even Mapping layer.

I've done a views with logic embedded. And then I've seen these views evolving. This was not pretty. Ended up gutting ALL the logic out of views and placing that into a QueryHandler<T>. So my rule of thumb is to do all calculations in BLL (or Query Handlers if you are using CQRS). And just give prepared data to a view. (Also this approach minimises the need for mapping layer). This way your view only has a Single Responsibility - display data in the required format.

As for mapping layer, again I prefer to have minimum logic there. I allow for DateTime to be converted to a String in format 2 Feb 2014, but anything more than that and you are in trouble again.

Paging is a spread-out concept. It is not really Business Logic, but also not a responsibility of a View. But because it goes so deep into the application, it ends up with BLL anyway (Or Query Handlers in our case).

OTHER TIPS

I'm not a fan of any real logic in the controllers. So, I'd move it to the existing BLL, or even a new component in the BLL if you want to keep it separate.

The reasons I take this approach is two fold.

First, this sort of logic tends to grow out of control, and it will really clutter up your controller actions. I like them to be very concise. (I generally have three things happen in them - Authentication, Data Retrieval, ViewModel construction. These are each achieved by calling an individual method in some form of BLL.)

The second reason, is because controller actions are more difficult to unit test, especially if they have a lot of messy logic. Structuring my controller actions this way really lends itself to good unit testing practices.

but there are other cases where a calculation is only ever going to be used for one view. In this case should the calculation instead go in the controller

Yes, Not only one time used calculation, but also calculations which are only used in presentation should go into Presentation layer itself. You business layer should be transparent to business needs and requirements. What you can do is create simple utilities or extensions folder and place all the most commonly used presentation layer calculations in there and reuse them.

if I can generalize a calculation and use it more than once it should go in the BLL,

Not exactly, if that calculation has got business relevance and importance, then it should go into BLL. Or else it should stay at presentation level itself.

In my opinion is better to do all business logic at one place and divide your business layer vertically (i.e. more granular service layer classes) not horizontally (more layers). I think that it is not problem if some of your business logic is view specific as you are using it only on web presentation layer. Keep it simple stupid and not overdesign:)

A generic function written as utility function and used in business layer should help. Let us hear from other people too

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top