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
My understanding is that CQRS combined with DDD would produce a query side that aggregated data across bounded context and a command side the executed commands strictly against the bounded context for that particular command.
This would leave your reporting to retrieve its data however it needed.
You could then inject some ICalculator into the query handler of the read side to do your business logic calculations.
E.g:
public class EmployeeQueryHandler : EmployeeIQueryHandler
{
private readonly INetWageCalculator _calculator;
private readonly IEmployeeRepository _repo;
public Repository(INetWageCalculator calculator, IEmployeeRepository repo)
{
_calculator = calculator;
_repo = repo;
}
public List ExecuteQuery()
{
var employees = _repo.GetEmployeeList();
foreach(var emp in employees)
{
// You have to get tax from somewhere, perhaps its passed in as
// a parameter...
emp.NetWages = _calculator.Calculate(emp.GrossWages, Tax);
}
return employees;
}
}
public class EmployeeRepository : IEmployeeRepository
{
List GetEmployeeList()
{
List empList = new List;
string query = "SELECT EMP_NAME, WAGES FROM EMPLOYEE";
...
..
while (reader.Read())
{
empList.Add(
new EmployeeViewModel
{
EmpName = reader["EMP_NAME"],
GrossWages = reader["WAGES"],
// This line moves to the query handler.
//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*/
}
);
}
}
}
This allows you to reuse the business logic of calculating net wages elsewhere using the same calculator service.
For performances sake, you could also inject the calculator into the repository if you didn't want to loop through the results twice.