2016-07-12 4 views
0

私は、ある時点で会計外部Webサービスに送信できる請求書集約ルートを持っており、そのサービスから取得したID /番号を維持して送信したものとしてマークします。DDDドメインサービス

DDDで正しい方法はありますか?

まずapprroach:

が機能SendToAccountingと請求書AggregateRootを持ち、会計への請求書をお送りしますドメインサービス/インターフェースを、注入、およびいくつかの「IDを取得/ここ

は私のアイデアです会計ソフトのコード」、および

Invoice.SendToAccounting(IInvoiceDomain service) 
{ 
    var accountingSoftwareID = service.getAccountingSoftwareId(this); 
    this.AccountingSoftwareId = accountingSoftwareId; 
} 

///Implementation in the application service 
    var invoice = _invoiceRepository.GetInvoiceById(id); 
    invoice.SendToAccounting(someDomainService); 
    _invoiceRepository.Update(invoice); 
    _unitOfWork.Save(); 

AccountingSoftwareIdプロパティを設定する第二のアプローチ:最初のアプローチが、ドメインサービスと同様の

は次のように永続化のために責任を負わなければならない:

var invoice = _invoiceRepository.GetInvoiceById(id); 
///unit of work save will be called inside this function 
invoice.SendToAccounting(someDomainService); 

サードapprocach:

ドメインサービスは、この動作

///Code inside domain service 
public void SendInvoiceToAccounting(int invoiceId) 
{ 
    var invoice = _invoiceRepository.GetInvoiceById(invoiceId); 
    string invoiceAccountingId = _accountingService.GetAccountingSoftwareId(invoice); 
    invoice.SetAsSentToAccounting(invoiceAccountingId); 
    _invoiceRepository.Update(invoice); 
    _unitOfWork.Save(); 
} 
にカプセル化するために、完全にrensponsibleになります
+0

会計に送信するプロセスには何が含まれているのかは不明です。これは何ですか? – tomliversidge

+0

外部サービスを呼び出す際に、どのように障害を処理しますか? – tomliversidge

+0

請求書集計内で使用されているaccountingIdは何​​ですか? – tomliversidge

答えて

1

DDDで正しい方法はありますか?

あなたの最初のアプローチは最も近いです。ドメインサービスのシグネチャは、集約ルート自体ではなく、引数として状態を受け入れる必要があります。

Invoice.SendToAccounting(IInvoiceDomain service) 
{ 
    var accountingSoftwareID = service.getAccountingSoftwareId(this.Id, ...); 
    this.AccountingSoftwareId = accountingSoftwareId; 
} 

渡される引数のすべての値型でなければなりません - ドメインサービスは、引数のコピーを操作することにより、集合体の状態を変更できないようにする必要があり、確かに実行できないようにする必要があり集約上の他のコマンド。

コードレビューでは、私はあなたが提供する2番目のアプローチを拒否します。ドメインモデルの観点からは、ドメインサービスインタフェースはコマンド(CQSの意味ではなく)ではなく、クエリを提供すべきです。

コードレビューでは、3番目のアプローチを完全に拒否します。集合体の設定はコードの匂いです。全体のポイントは、それを更新するためのルールで状態をカプセル化することです。

しかし

あなたが同じトランザクションで2つの異なる場所に書き込みをしているという点で、デザインは、やや憂慮すべきです。幸いなことに、それは大きな問題ではありませんが、アカウンティングサービスで実行されるコマンドが成功した場合にはどうしたらよいでしょうか?しかし、更新された請求書の保存に失敗しますか?

分散トランザクションが魅力的ではないと仮定すると、Udi Dahanが何を言っているかを、reliable messagingについて検討したいと思うかもしれません。

0

私の最初の考えは「会計の一部を請求していないのですか? :)

オプション1は、私のドメインオブジェクトが動作する過去に使用してきたものです。

私はオプション2を好きではないので、請求書はリポジトリへのプライベートリファレンスが必要です。

もっと一般的な見解では、ここではドメイン内で多くの動作がないように見えます。これはIDを設定しているようです。オプション3はこれをキャプチャするようです。アプリケーションサービスが十分で、ちょうど次

  1. 請求書をロード座標ならば、私は思ったんだけど、請求書上に保存かなりのオプション3である

をAccountingId

  • を取得上記。私はリポジトリとサービスを渡すように誘惑されるだろうが、それは本当にちょうどもっと機能的なスタイルだ - 上記はプライベートフィールドでも機能するだろう。

  • 0

    BCは、指定された請求書IDに対して常に同じaccountingSoftwareIdを返す必要があります。

    最初のラウンドではBCがコールされたが、請求書の更新が失敗した場合は、BC州には状態t1、BCには州t0があります。コマンドを再試行すると、同じ呼び出しが実行され、同じIDが返されます。更新が成功すると、BCごとにt1状態になります。最悪の場合、コマンドを手動で解決する必要がある場合でも、結果として得られるアカウントIDは、指定された請求書IDに対して常に同じになります。

    特定の請求書の会計IDを解決するには、会計BCに直接問い合わせることができます。