1

私は DDD の概念に不慣れで、永続化レイヤーからドメイン モデルを再構築するときにいくつかの問題に直面しています。つまり、ビジネス ルールのために通常は許可されないオブジェクトの作成を処理する方法です。

たとえば、Invoice と InvoiceRows の概念です。ビジネス ルールでは、請求書が顧客に送信された後は、請求書行を請求書に追加することはできません。

私のドメイン モデルは次のようになります。

class Invoice
{
    List<InvoiceRow> _rows = new List<InvoiceRow>();

    public bool IsSent { get; private set; }

    Invoice(bool isSent)
    {
        this.IsSent = isSent;
    }

    public InvoiceRow AddRow(Product product, decimal amount)
    {
        if (IsSent) throw new InvalidOperationException("Invoice already sent to customer.");

        var row = new InvoiceRow(this, product, amount);

        _rows.Add(row);

        return row;
    }

    public void Send(object service)
    {
        if (IsSent) throw new InvoiceAlreadySentException();

        service.SendInvoice(this);

        this.IsSent = true;
    }
}

class InvoiceRow
{
    public Product Product { get; private set; }
    public decimal Amount { get; private set; }
    public Invoice Invoice { get; private set; }

    InvoiceRow(Invoice parent, Product product, decimal amount)
    {
        this.Invoice = parent;
        this.Product = product;
        this.Amount = amount;
    }
}

すでに送信されているデータベースからの行を含む請求書モデルを再構築すると、請求書がすでに送信されている場合、請求書行の追加がドメイン モデルによって拒否されるという問題が発生します。

例えば:

Invoice invoice = new Invoice(invoiceDto.IsSent);

foreach(row in invoiceRowsDto)
{
    invoice.AddRow(row.Product, row.Amount); // Not allowed because the invocie has been sent...
}

もちろん、行のリストを含むコンストラクター パラメーターを追加することは可能ですが、これにより、同じ行のリストを別の請求書に追加することが可能になります。

var listOfRows = somelistofinvoicerowsretrievedfromdatabase;
var invoice1 = new Invoice(issent=true, listofrows);
var invoice2 = new Invoice(issent=false, listofrows);

この問題を解決する最善の方法は何ですか?

4

1 に答える 1