这里是一个简单的例子,我正在运行的问题不在于这里提供的一些想法和其他关于DDD的地方.
说我有一个ASP.NET MVC 3网站创建/操纵一个人.控制器访问应用程序服务层(PersonService),后者又使用域实体(EF 4 POCO)和PersonRepository进行更改并持久化.为了简单起见,我在这里省略了所有的界面.在这种情况下,人是根,为了简单起见,只有电子邮件地址(也假定电子邮件不是不可变的,可以更新).
选项1:
尝试坚持使用DDD的基础知识,其中与实体直接相关的行为实现为实体的一部分(Person实现AddEmail,ChangeEmail等).唯一的问题是,除了Add *方法之外,Person将需要知道上下文或实体框架(将删除任何持久性无知)或需要使用“服务”或存储库来标记电子邮件已修改.
选项二:
让个人服务使用存储库来添加/更新电子邮件地址,并且不对该实体执行行为.在许多关系(例如地址,两个表需要更新以完成工作)的情况下,这种情况要简单得多,但是模型就变成了一大堆的getter和setter.
无论如何,有什么想法吗?
谢谢Brian
选项1是要走的路.
推理是简单的 – 更改电子邮件地址是领域关注.我敢打赌你的域名专家说他们将需要更改电子邮件.自动将电子邮件更改的逻辑标记为应该在域模型中生活的业务逻辑.对象主要由他们的行为定义,而不是他们所持有的数据.
另外 – 在您选择使用工作单位之前,先考虑一下,并将所有服务都包装起来.总结根应该是绘制事务边界,如果服务器只包含存储库和域对象调用,服务通常是无用的.
我会有这样的事情:
@H_403_6@public class Person{ public Email Email{get;private set;} public void SpecifyEmail(Email email){ //some validation,if necessary EnsureEmailCanBeChanged(); //applying state changes Email=email; //raising event,if necessary Raise(new EmailChanged(this)); } public class EmailChanged:Event<Person>{ public EmailChanged(Person p):base(p){} } } public class Email{ public Email(string email){ //validations (e.g. email format) Value=email; } //implicit to string,explicit from string conversions } public class PersonController{ public ActionResult SpecifyEmail(int person,string email){ _persons.Get(person).SpecifyEmail((Email)email); return RedirectToAction("Person",new{person}); } }我正在使用NHibernate – 它足够聪明,以确定自从上次持续存在以来发生了什么变化.很难说实体框架如何处理这个.