域驱动设计 – 域驱动设计 – 如何处理聚合根部分的更新
背景:我有一个Person域对象.它是一个聚合根.我已经在下面列出了一部分课程.
我正在公开执行对象行为的方法.例如,要添加BankAccount,我有AddBankAccount()方法.我没有包括该类的所有方法,但足以说必须使用方法更新任何公共属性. 我将创建一个IPerson存储库来处理CRUD操作. public interface IPersonRepository { void Save(Person p); //...other methods } 问题:在更新现有人员时,如何告知存储库需要更新哪些字段?例如,如果我向现有人员添加银行帐户,当调用repository.Save()时,如何将此信息传递给存储库? 在存储库中,很容易确定何时创建新人,但是当存在现有人员并且您更新该人员的字段时,我不确定如何将其传达给存储库. 我不想用有关哪些字段更新的信息污染我的Person对象. 我可以在存储库上有单独的方法,如.UpdateEmail(),AddBankAccount(),但这感觉有点矫枉过正.我想在存储库上使用一个简单的.Save()方法,它确定需要以某种方式更新的内容. 别人怎么处理这种情况? 我搜索了网络和stackoverflow但没有找到任何东西.我一定不能正确搜索,因为在DDD范例中持久化时,这似乎很简单.我也可以对DDD有所了解:-) public class Person : DomainObject { public Person(int Id,string FirstName,string LastName,string Name,string Email) { this.Id = Id; this.CreditCards = new List<CreditCard>(); this.BankAccounts = new List<BankAccount>(); this.PhoneNumbers = new List<PhoneNumber>(); this.Sponsorships = new List<Sponsorship>(); } public string FirstName { get; private set; } public string LastName { get; private set; } public string Name{ get; private set; } public string Email { get; private set; } public string LoginName { get; private set; } public ICollection<CreditCard> CreditCards { get; private set; } public ICollection<BankAccount> BankAccounts { get; private set; } public ICollection<PhoneNumber> PhoneNumbers { get; private set; } public void AddBankAccount(BankAccount accountToAdd,IBankAccountValidator bankAccountValidator) { bankAccountValidator.Validate(accountToAdd); this.BankAccounts.Add(accountToAdd); } public void AddCreditCard(CreditCard creditCardToAdd,ICreditCardValidator ccValidator) { ccValidator.Validate(creditCardToAdd); this.CreditCards.Add(creditCardToAdd); } public void UpdateEmail(string NewEmail) { this.Email = NewEmail; }
有一个来自
S#arp Architecture项目的Repository接口的示例.它类似于
PoEAA Data Mapper,因为它也用于CRUD操作.
public interface IRepositoryWithTypedId<T,IdT> { T Get(IdT id); IList<T> GetAll(); IList<T> FindAll(IDictionary<string,object> propertyValuePairs); T FindOne(IDictionary<string,object> propertyValuePairs); T SaveOrUpdate(T entity); void Delete(T entity); IDbContext DbContext { get; } } 如您所见,实体的特定属性没有更新方法.整个实体作为参数提供给SaveOrUpdate方法. 当您的域实体的属性被更新时,您应该告诉您的Unit of Work该实体是“脏”的并且应该保存到存储中(例如数据库) 您不应该使用有关更新字段的信息污染您的Person对象,但如果实体已更新,则需要跟踪信息. 可能有类DomainObject的方法告诉’工作单元’实体是’新’,’脏’还是’删除’.然后您的UoW本身可能会调用正确的存储库方法 – “SaveOrUpdate”或“删除”. 尽管像NHibernate或EntityFramework这样的现代ORM框架有自己的“工作单元”实现,但人们倾向于为它们编写自己的包装/抽象. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |