1

I have a question concerning an issue that has already been disputed many times in stackoverflow (I apologize for this) but no general answer has ever been given because of the subjectivity of the topic from one case to another: can we add business logic to the repository layer according to the repository pattern? I have an MVC 3 application with ViewModels (that means I don't use the ViewData at all). The model is an LinqtoSQL EF of course connected to a database. Currently I am accessing the entities directly from the controllers which contain all the business logic and I wrap the data needed for the Views in specific ViewModels. Now I am starting to refactor and I realized that the best way to avoid code duplication, besides optimizing the ViewModels, is to delegate all the queries to a repository, which communicates with the EF, and create tailored methods to be used by the controller. Now, taking into account that I would like the repository to return actual objects and not expressions, I was thinking about delegating small pieces of business logic to the repository in order to make my code clearer. However for the sake of loose coupling, I would like to have your opinion. In the code shown below (which currently resides in the controller) all the variables except lprojectionPercactualValue are taken from the database. Therefore I wanted to move this piece of code to the repository and call a method with signature:

public string getColor (int ItemId, float lprojectionPercactualValue);

The method needs the ItemId in order to retrieve the values specific for that Item. What do you think about this design decision? Is it better to leave the code in the controller, move to another method still in the controller (create a method or even a class dedicated) or move it to the repository as explained?

if (litem.Ascending == true)
{
    if (lprojectionPercactualValue < lminThreshold)
    {
        lcolor = "RED";
    }
    else if (lprojectionPercactualValue > lminThreshold && lprojectionPercactualValue < lmedThreshold)
    {                                   
        lcolor = "YELLOW";
    }
    else //(percValue >= item.Max_Threshold)
    {
        lcolor = "GREEN";
    }
}

else
{
    if (lprojectionPercactualValue > lminThreshold)
    {
        lcolor = "RED";
    }
    else if (lprojectionPercactualValue < lminThreshold && lprojectionPercactualValue > lmedThreshold)
    {
        lcolor = "YELLOW";
    }
    else //(percValue <= item.Max_Threshold)
    {
        lcolor = "GREEN";
    }
}
Jeff LaFay
  • 12,882
  • 13
  • 71
  • 101
CiccioMiami
  • 8,028
  • 32
  • 90
  • 151

3 Answers3

0

It is not recommended.

How does Repository now about the lminThreshold? What if this value itself needs to come from a lookup table or a config file?

Move it to business layer - and if you do not have one, to the controller.

Aliostad
  • 80,612
  • 21
  • 160
  • 208
  • @Aliostad: what do you consider as business layer in a MVC application? Although many people confuse the controller with the business service layer, I usually prefer to consider the model as business service layer (according to [COMBINE 4+2](http://modelbased.net/comet/service_modelling/4c_Service_metamodel_html.html) layers). Therefore, I consider the EF + the repository class and of course the controller, as the business service layer. May you tell me your interpration please? thanks – CiccioMiami Apr 07 '11 at 13:01
  • Business layer is one that sits between repository and controller. You might not necessarily need one but this sort of operation (translating values) is suitable for a business layer component. You may put it in controller but what if you need it in more than one controller? – Aliostad Apr 07 '11 at 13:04
  • @Aliostad: so would you consider a Repository class part of the Business layer? If not, would you create: 1) a set of classes (business layer) with methods exposed to every controller in the application 2) that get data from the Repository class, which exposes method to the business layer and get data from the 3) EF which gets data from the 4) Database? Is that correct? Thanks – CiccioMiami Apr 07 '11 at 13:18
  • What you are talking about requires another question. – Aliostad Apr 07 '11 at 13:21
  • @Aliostad: sorry, so I restrict the question: would you consider a Repository class part of the Business layer? I ask you this because I do not know what do you refer to when you say repository, the actual repository (the db) or the repository class – CiccioMiami Apr 07 '11 at 13:29
  • Repository is not part of the business layer. It is part of the database access layer DAL in a tiered architecture. The only reason I said this deserves its own question was so that others could also benefit from the discussion. – Aliostad Apr 07 '11 at 13:33
  • Ok, you are right, I am creating another question to go deep in this topic. I hope you are going to join! – CiccioMiami Apr 07 '11 at 14:07
0

Wrap your EF logic inside a DAL layer that you proxy via a Repository class. This is raw data and since you require additional crunching on it, it is recommanded to have a service layer that uses it and applies your custom business rules over it. The Repository here is meant to discourage any DB code duplication.

At this point, you only check if the lprojectionPercactualValue goes over some treshold, but what if, at some point, you will need to compute that treshold in some fancy manner or you decide to perform some sort of validation or some other thing like that. These are all domain specific decisions and they should reside in a layer of their own.

doer
  • 11
  • 1
  • What do you mean with EF logic? The EF is automatically generated by LINQtoSQL from the data in the database and I thought that EF was representing the DAL. The thresholds are calculated by another application and for my application they have to be considered as stored in a database or in the future taken from a web service. In short do you suggest me to put the above code in a Repository class? – CiccioMiami Apr 07 '11 at 13:25
0

IMHO, you'd better to add a business layer between controller and repository, and put your getColor code above into the business layer (or even break it into several methods if needed), what if you need it in other controllers, what if it is no longer a simple if/else, what if you have to get the thresholds values from a Web service tomorrow, do you want to have make all those changes in your controller or repository code?

Tien Do
  • 10,319
  • 6
  • 41
  • 42