私はあなたがほとんどそこにいると思います。良い解決策に近い。これら2つを2つのBCに分割する必要があるかどうかはわかりません。User Aggregateroot (?) と Game は 1 つの BC に属し、相互に依存している可能性があります。ユーザーは「1つまたは複数の」ゲームへの「メンバーシップ」を持っています(エンティティの関係を推測するだけです)。しかし、私は今ブレインストーミングを行っているところです。従うようにしてください:)さまざまなアプローチが続きます:
最初
の GameBC には、実際に UserMembership をパラメータとして取る Create() メソッドがあります。(ユーザー メンバーシップ) を作成します。次に、UserMembership エンティティを通じて、メンバーシップの種類とこれがユーザーであることがわかります。承認された場合、ゲームが作成されます。例外がスローされない場合、またはゲームがルール違反メッセージを受け取る場合は、クライアントにどのようなアプローチで通信するかによって異なります。ドメインの知識を漏らすことなく、アプリケーション層で調整を行うことができます。
2番目
に、他の回答の1つとして行います。Game.Create(UserId) メソッド内で CreateGameEvent を発生させます。そのイベントは、アプリケーション層に存在し、リポジトリを介して UserMembership を検索する EventHandler (アプリケーションの起動時に IoC によって登録される) によってキャッチされます。ドメイン知識のわずかな漏えいは、アプリケーション層で検証されることを誰が許可されているかを知るビジネス ルールです。これは、CreateGameEventHandler に UserId と RuleRef (文字列「CAN_CREATE_GAME」または列挙型) を取得させ、UserPermission オブジェクトに権限を確認させることで解決できます。そうでない場合。アプリケーション層で例外がスローされ、キャッチされます。欠点は、Create メソッドでアクセス許可参照文字列をハードコーディングする必要がないことです。
3
番目は、2 番目のアプローチが終了するところまで続きます。SRP の原則に従っている場合、GameBC はユーザー権限の検索を行うのに適切な場所ではない可能性があることを知っています。しかし、何らかの形でそのメソッドの周りでアクションがトリガーされます。別の方法として、Create (GroupLeader ユーザー) を使用することもできます。または、Game.Create(User user) を使用して、User が GroupLeader タイプであることを検証できます。Create(GroupLeader) は、このメソッドを呼び出す必要があることを示します。
最後
これを書いているとき、私が今より好きな代替案かもしれません。エンティティを作成するときは、通常、その Create(Save) メソッドをリポジトリに配置します。IGameRepository インターフェイスは、ドメイン アセンブリ プロジェクトの Game Entity の隣にあります。ただし、Game Entity のライフサイクルの開始を担当する GameFactory を作成することもできます。ここにも Create メソッドを置くのに適した場所があります... GameFactory.Create(GroupLeader) { return new Game.OwnerUserId = GroupLeader.Id; 次に、それを保存するだけです IGameRepository.Save(Game)
次に、他の開発者に「ゲームを作成するには GroupLeader インスタンスが必要です」と伝える直感的で自己記述的な方法があります。
最後に、ドメインを知っていること、そして自分に最も適したものを見つけられることを願っています。実用的になり、Eric Evan のハードコアに行かないでください。物事がどのように行われるかという「宗教」に固執している開発者が非常に多くいます。プロジェクトの規模、お金、時間、他のシステムへの依存度なども、DDD をどれだけ厳密に実行できるかに影響します。
幸運を。