一般的に、DDD とドメイン モデリングの経験が豊富な人からのガイダンスを探しているという一般的なシナリオがあります。
ブログ エンジンの構築を開始するとします。最初の要件は、記事が投稿された後、ユーザーがコメントを投稿できるようにすることです。これは問題なく開始され、次の設計につながります。
public class Article
{
public int Id { get; set; }
public void AddComment(Comment comment)
{
// Add Comment
}
}
私のMVCコントローラーは次のように設計されています:
public class ArticleController
{
private readonly IRepository _repository;
public ArticleController(IRepository repository)
{
_repository = repository;
}
public void AddComment(int articleId, Comment comment)
{
var article = _repository.Get<Article>(articleId);
article.AddComment(comment);
_repository.Save(article);
return RedirectToAction("Index");
}
}
これですべてが正常に機能し、要件を満たしています。次のイテレーションでは、コメントが投稿されるたびに、ブログの作成者に通知メールを送信する必要があります。
この時点で、私が考えることができる2つの選択肢があります。1) アーティクルを変更して IEmailService を要求するか (ctor で?)、DI コンテナーへの静的参照から EmailService を取得します。
1a) かなり醜いようです。私のエンティティがサービスを認識しているドメイン モデル ルールに違反していると思いますか?
public class Article
{
private readonly IEmailService _emailService;
public Article(IEmailService emailService)
{
_emailService = emailService;
}
public void AddComment(Comment comment)
{
// Add Comment
// Email admin
_emailService.SendEmail(App.Config.AdminEmail, "New comment posted!");
}
}
1b) また、醜いようですが、静的にアクセスされる構成済みの DI コンテナーが必要になりました。
public class Article
{
public void AddComment(Comment comment)
{
// Add Comment
// Email admin
var emailService = App.DIContainer.Resolve<IEmailService>();
emailService.SendEmail(App.Config.AdminEmail, "New comment posted!");
}
}
2) IArticleService を作成し、AddComment() メソッドを記事エンティティ自体ではなくこのサービスに移動します。
このソリューションはよりクリーンだと思いますが、コメントを追加することは発見されにくくなり、作業を実行するには ArticleService が必要になります。AddComment は Article クラス自体に属する必要があるようです。
public class ArticleService
{
private readonly IEmailService _emailService;
public ArticleService(IEmailService emailService)
{
_emailService = emailService;
}
public void AddComment(Article article, Comment comment)
{
// Add comment
// Email admin
_emailService.SendEmail(App.Config.AdminEmail, "New comment posted!");
}
}
public class ArticleController
{
private readonly IRepository _repository;
private readonly IArticleService _articleService;
public ArticleController(IRepository repository, IArticleService articleService)
{
_repository = repository;
_articleService = articleService;
}
public void AddComment(int articleId, Comment comment)
{
var article = _repository.Get<Article>(articleId);
_articleService.AddComment(article, comment);
_repository.Save(article);
return RedirectToAction("Index");
}
}
したがって、私は基本的に、ドメイン モデリングの経験が豊富な人からのアドバイスを求めています。より明白な解決策が見つからない場合は、お知らせください:)
サービスオプションは見つけにくいため、正直なところ、どちらのソリューションも一般的に嫌いです。ArticleService を利用できないと、記事のインスタンスにコメントを追加できなくなりました。また、AddComment は Article 型の明白なメソッドのように見えるため、あまり自然ではないように感じます。
とにかく、私は入力を読むのを楽しみにしています。前もって感謝します。