Mat*_*ger 45 c# bdd domain-driven-design inversion-of-control
我有一个常见的场景,我正在寻找一些有DDD和域建模经验的人的指导.
假设我开始构建一个博客引擎,第一个要求是在发布文章后,用户可以开始在其上发布评论.这开始很好,并导致以下设计:
public class Article
{
public int Id { get; set; }
public void AddComment(Comment comment)
{
// Add Comment
}
}
Run Code Online (Sandbox Code Playgroud)
我的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");
}
}
Run Code Online (Sandbox Code Playgroud)
现在一切正常,它符合要求.下一次迭代我们得到一个要求,即每次发布评论时,博客作者都应该收到一封电子邮件通知他.
在这一点上,我有两个我能想到的选择.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!");
}
}
Run Code Online (Sandbox Code Playgroud)
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!");
}
}
Run Code Online (Sandbox Code Playgroud)
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");
}
}
Run Code Online (Sandbox Code Playgroud)
所以我基本上都是寻求在域建模方面经验丰富的人的建议.如果我错过了一个更明显的解决方案,请告诉我:)
我一般不喜欢这两种解决方案,因为服务选项不易被发现.在没有ArticleService可用的情况下,我再也无法为文章的实例添加注释.它也感觉不太自然,因为AddComment在Article类型上看起来就像是一个显而易见的方法.
无论如何,我期待着阅读输入.提前致谢.