My domain model has a lot of complex financial data that is the result of fairly complex calculations on multiple properties of various entities. I generally include these
You can encapsulate logic by creating a class that contains the original Entity and the additional calculated property. You then create helper methods that project to the class.
For example, if we were trying to calculate the tax for an Employee and a Contractor entity, we could do this:
//This is our container for our original entity and the calculated field
public class PersonAndTax
{
public T Entity { get; set; }
public double Tax { get; set; }
}
public class PersonAndTaxHelper
{
// This is our middle translation class
// Each Entity will use a different way to calculate income
private class PersonAndIncome
{
public T Entity { get; set; }
public int Income { get; set; }
}
Income calculating methods
public static IQueryable> GetEmployeeAndTax(IQueryable employees)
{
var query = from x in employees
select new PersonAndIncome
{
Entity = x,
Income = x.YearlySalary
};
return CalcualateTax(query);
}
public static IQueryable> GetContratorAndTax(IQueryable contractors)
{
var query = from x in contractors
select new PersonAndIncome
{
Entity = x,
Income = x.Contracts.Sum(y => y.Total)
};
return CalcualateTax(query);
}
Tax calculation is defined in one place
private static IQueryable> CalcualateTax(IQueryable> personAndIncomeQuery)
{
var query = from x in personAndIncomeQuery
select new PersonAndTax
{
Entity = x.Entity,
Tax = x.Income * 0.3
};
return query;
}
}
Our view model projections using the Tax property
var contractorViewModel = from x in PersonAndTaxHelper.GetContratorAndTax(context.Contractors)
select new
{
x.Entity.Name,
x.Entity.BusinessName
x.Tax,
};
var employeeViewModel = from x in PersonAndTaxHelper.GetEmployeeAndTax(context.Employees)
select new
{
x.Entity.Name,
x.Entity.YearsOfService
x.Tax,
};