Following the concept of CQRS (Command Query Responsibility Segregation), I am directly referring the DAL in my MVC application and doing all reads via the ViewModels. However a colleague of mine is asking me what will you do when any business logic has to be applied when doing a read. For e.g. if you need to compute a percentage value in scenario like below:
//Employee domain object
class Employee
{
string EmpName;
Single Wages;
}
//Constant declared in some utility class. This could be stored in DB also.
const Single Tax = 15;
//View Model for the Employee Screen
class EmployeeViewModel
{
string EmpName;
Single GrossWages;
Single NetWages;
}
// Read Facade defined in the DAL
class ReadModel
{
List<EmployeeViewModel> GetEmployeeList()
{
List<EmployeeViewModel> empList = new List<EmployeeViewModel>;
string query = "SELECT EMP_NAME, WAGES FROM EMPLOYEE";
...
..
while(reader.Read())
{
empList.Add(
new EmployeeViewModel
{
EmpName = reader["EMP_NAME"],
GrossWages = reader["WAGES"],
NetWages = reader["WAGES"] - (reader["WAGES"]*Tax)/100 /*We could call a function here but since we are not using the business layer, the function will be defined in the DAL layer*/
}
);
}
}
}
In above example, there is a calcuation occuring during the read which is occuring in the DAL layer. We could have created a function to do the calculation but again since we have bypassed the business layer for our read, the function will be located in the DAL. Even worse, someone might do it directly in the DB in a stored proc if the value of Tax is stored in the DB. So we have a potential leakage of business logic here in other layers.
You might say why don't you store the computed value in a column while doing the command. So let us change the scenario a bit. Let us say you are showing the potential Net Wages for the employee in a report with the current Tax rate and the Wages are yet to be paid.
How would you handle this in CQRS ?