Wpf 在域层和表示层之间共享的DDD中,将业务逻辑放在何处?

Wpf 在域层和表示层之间共享的DDD中,将业务逻辑放在何处?,wpf,mvvm,domain-driven-design,Wpf,Mvvm,Domain Driven Design,我正在使用DDD模式开发应用程序 我在域层有Invoice类 public class Invoice { List<InvoiceLine> list = new List<InvoiceLine>(); public DateTime Date { get; set; } public Customer Customer { get; set; } public decimal GrandTotal {

我正在使用DDD模式开发应用程序

我在域层有
Invoice

public class Invoice
{
    List<InvoiceLine> list = new List<InvoiceLine>();

    public DateTime Date { get; set; }

    public Customer Customer { get; set; }

    public decimal GrandTotal 
    { 
        get
        {
            // Simplified grand total. 
            // It's actually include tax and discount to calculate.

            decimal total = 0m;
            foreach(InvoiceLine line in Lines)
                total += line.LineTotal;

            return total;
        }
    }

    public IEnumerable<InvoiceLine> Lines
    {
        get { return list; } 
    }

    public void AddLine(InvoiceLine line)
    {
        lines.Add(line);
    }
}
公共类发票
{
列表=新列表();
公共日期时间日期{get;set;}
公共客户客户{get;set;}
公共十进制总计
{ 
得到
{
//简化总数。
//它实际上包括税和折扣来计算。
小数总数=0米;
foreach(发票行中的行)
合计+=行。行合计;
返回总数;
}
}
公共可数线
{
获取{返回列表;}
}
公共无效添加行(发票行)
{
行。添加(行);
}
}
我使用的是mvvm模式,所以我还有一个viewmodel来编辑发票。我的问题是我应该将业务逻辑放在哪里来计算GrandTotal,以便域和表示上的业务逻辑相同?


我是否应该将代码从域复制到演示文稿(
Invoice
InvoiceViewModel
)?或者创建一个域和表示都可以使用的服务?

DDD中聚合的主要目标是保持一致性-在您的情况下,一致性意味着GrandTotal始终具有正确的值。也就是说,并没有规定聚合类不能使用其他类来获得这种一致性

例如,您可以提供一个类,该类的唯一职责是计算总计并在域和视图模型中使用它。我不会称之为服务,因为它与DDD概念无关。例如:

public interface IInvoiceLine
{
    decimal Amount {get;}
}

public interface ICalculateGrandTotal
{
    decimal Calculate(IEnumerable<IInvoiceLine> lines);
}

public class GrandTotalCalculator: ICalculateGrandTotal
{
    ...
}
公共接口IInvoiceLine
{
十进制数{get;}
}
公共接口ICalculateGrandTotal
{
十进制计算(IEnumerable行);
}
公共类GrandTotalCalculator:ICalculateGrandTotal
{
...
}

现在,您可以在视图模型和域中使用此计算器,而无需重复代码。此外,由于接口的原因,视图模型和域类之间没有直接耦合<代码>IInvoiceLine接口可以通过视图模型和域实体分别实现。

这是一个很好的解决方案。谢谢