これはかなり長い間私を悩ませてきたものです。私はこの1年にわたってさまざまなアプローチを試みましたが、私は常にこれを反映するために戻ってくるので、ここに身を置きます!
ですから、まず共通点を得ます。ブルーブックに従っている場合、トランザクション処理はアプリケーションサービスで行う必要があります。トランザクションを開き、1つまたは複数の集約を取得し、1つの集約のみを適合させて、そのトランザクションをコミットします。 (トランザクションごとに1つの集計)。
次にドメインイベントの理論に従うと、2つのキャンプがあり、1つはコミット前のイベントの発行、もう1つはコミット後のイベントの発行です。私は2番目のもので大丈夫なので、そのコンテキストにとどまりましょう。
わかりました。これについてはさまざまなアプローチがありました。自分で判断したり、他の選択肢を見つけたりできるように説明します。
私は.NETを使用しています。
ですから、私の最初の試みは非常に簡単で、今でも使用しています。
次のような2つのメソッドを持つ汎用リポジトリがあります。
public interface IRepository<TId, T> where T : Aggregate
{
T GetById(TId id);
Save(T aggregate);
}
そして、私の保存メソッドでは、いくつかのことを行います:
ご覧のとおり、Saveメソッドはかなりの数の処理を実行します。おそらく、その一部がその責任の範囲外と見なされます。しかし、私のアプリケーションサービスには実際にはトランザクションが含まれておらず、保存ごとにトランザクションがコミットされるため、この方法を使用することは非常に簡単な経験でした。
私にとっての2番目のアプローチは、エンティティフレームワークの.SaveChangesメソッドをオーバーライドすることでした。基本的に、追跡された集約のリストを取得し、それらのイベントを取得します。次に、実際にコミットするbase.SaveChanges()メソッドを呼び出して、イベントをディスパッチします。
この場合、リポジトリのsaveメソッドは、エンティティを変更トラッカーに保存するときにのみ変更トラッカーにアタッチします(変更追跡なしでエンティティを取得し、.Saveパーツの変更のみを追跡する傾向があります。これは、情報目的で同じ方法ですが、変更されるのはそのうちの1つだけです)。
次に、DbContextを次のようにIUnitOfWorkインターフェイスにラップします。
public interface IUnitOfWork
{
void Commit();
}
そしてcommitメソッドがcontext.SaveChanges();を呼び出します。メソッド。コミット後にイベントをディスパッチするようにオーバーライドされています。
次に、私のアプリケーションサービスは必要なリポジトリを挿入し、それらの1つで.Save()メソッドを呼び出し、注入されたuowをコミットします。
これら2つについて私が抱えている問題は、E.F。のコンテキストにあります。それらは、私がやりたいことに対して必ずしも100%正しいとは限りません。
アプリケーションサービスでトランザクションスコープを開くと、UoWでリポジトリに保存/コミットするときに、どちらのメソッドも実際にイベントを発行しますが、親トランザクションスコープをロールバックすると、無効な状態になります。
私の最終的な目標は、アプリケーションサービスでトランザクションスコープを常に使用し、そのトランザクションスコープのcommitを使用して、コンテキストの.SaveChanges()メソッドの代わりに実際に変更をコミットし、トランザクションスコープがコミットされた後にのみイベントをディスパッチすることです。
さて、私の質問は次のとおりです。最初の2つのアプローチはあなたにとって正しいように見えますか?そして、私は細かい詳細について心配していますか?私の3番目のアイデアは実際に正しい方法で達成できますか?余分な代替案を見逃す可能性はありますか?
ありがとうございます !