I'm developing a ASP.NET MVC application with 3 layer classic architecture 1. data access (Repositories) 2. Business logic (Services ) 3. Application layer (MVC Controller classes) The task is follow there is domain class Learner and learners can take exams, taking an exam produce an order (Order class), after that the learner take an exam, we need to release results of exam for each learner(this mean give a mark and grade) and has some business rule that need to be verified 1. the results hasn't been released yet 2. all learner who has status present should has mark 3. grading boundary should be confirmed (marks and grade for exam) When user do release results all this rules should validate and if some rule doesn't satisfied should display an error message. I decided that all logic related to validation business rules keep in the Service class and if any rule not pass throw specific exception, in the controller class this exception will catch and display error to the client. Here is the code
Service class
public void ReleaseResults(long orderId)
{
var order =orderRepository.Get(orderId);
Check.Require(order != null, "Order was not found");
if (IsOrderReleased(order))
{
throw new ReleaseResultsException("The results has been already released", order.OrderNo);
}
if (AllLearnersHasStatusPresentAndMark(order))
{
throw new ReleaseResultsException("One or more learners unmarked", order.OrderNo);
}
if (!GradingBoundaryConfirmed(order))
{
throw new ReleaseResultsException("The Grading boundary needs to be confirmed", order.OrderNo);
}
foreach (var learnerDetail in order.LearnerDetails)
{
if (HasNotStatusPresent(learnerDetail))
{
continue;
}
learnerDetail.SetReleasedResults();
}
orderRepository.SaveOrUpdate(order);
}
Controller class
public ActionResult Release(EncryptedId orderId)
{
Check.Require(orderId != null, "The parameter orderId was null");
try
{
orderReleaseResultsService.ReleaseResults(orderId);
}
catch (ReleaseResultsException e)
{
return Content(string.Format("Error: {0}", e.Message));
}
return Content(MUI.TheResultsHasBeenReleased);
}
I am not sure if this is best way to validate business rules, can anyone help me with suggestions or better solution of this problem? Thanks in advance!
I would avoid using exceptions for validation purposes but rather have methods that return true/false. Obviously for some tasks where validation is data at the data tier (for example enforcing database constraints) you could use exceptions.
You may take a look at the following tutorial about validating at the service layer.