這裏是我跨運行沒有一些關於DDD這裏提出的觀點和其他地方齧合問題的一個簡單的例子。DDD,實體框架,總結實體行爲(Person.AddEmail等)
說我有一個ASP.NET MVC 3網站創建/操縱的人。控制器訪問應用程序服務層(PersonService),後者又使用域實體(EF 4 POCO)和PersonRepository進行更改並保存它們。爲了簡單起見,我將這裏的所有界面都拋棄了人是這種情況下的根源,爲了簡單起見,只有電子郵件地址(也假定電子郵件不是不可變的,並且可以更新)。
選項1: 嘗試堅持[我的理解] DDD的基礎知識,其中與實體直接相關的行爲作爲實體的一部分實現(Person實現AddEmail,ChangeEmail等)。除了Add *方法之外,唯一的問題是Person需要知道上下文或實體框架片斷(這會刪除任何持久性的無知),或者需要使用「服務」或存儲庫來標記修改後的電子郵件。
// Person Service
public class PersonService {
// constructor injection to get unit of work and person repository...
// ...methods to add/update a person
public EmailAddress AddEmailAddress(int personId, EmailAddress email)
{
Person p = personRepository.Find(p => p.Id == personId).First();
p.AddEmail(email);
uow.SaveChanges();
return email;
}
public EmailAddress ChangeEmailAddress(EmailAddress email)
{
Person p = personRepository.Find(p => p.Id == personId).First();
p.ChangeEmail(email);
// change state of email object here so it's updated in the next line???
// if not here, wouldn't the Person entity have to know about the context
// or use a service?
uow.SaveChanges();
return email;
}
}
// Person Repository
public class PersonRepository
{
// generic repository implementation
}
// Person Entity
public class Person
{
public string Name { get;set; }
public IEnumerable<EmailAddress> EmailAddresses { get;set; }
public void AddEmail(EmailAddress email)
{
this.EmailAddresses.Add(email);
}
public void ChangeEmail(EmailAddress email)
{
EmailAddress orig = this.EmailAddresses.First(e => e.Id == email.id);
// update properties on orig
// NOW WHAT? [this] knows nothing about the context in order to change state,
etc, or do anything to mark the email add updated
}
}
// Email
public class EmailAddress
{
public string Email { get;set; }
public bool IsPrimary { get;set; }
}
選項2: 讓人服務使用的存儲庫來添加/更新的電子郵件地址和不落實的人實體的行爲。在多對多關係的情況下(例如,需要更新兩個表以完成工作的地址),這種情況要簡單得多,但模型變得「貧乏」只是一羣吸氣和吸氣人員。
// Person Service
public class PersonService {
// constructor injection to get unit of work and person repository...
// ...methods to add/update a person
public EmailAddress AddEmailAddress(int personId, EmailAddress email)
{
Person p = personRepository.Find(p => p.Id == personId).First();
personRepository.AddEmail(personId, email);
uow.SaveChanges();
return email;
}
public EmailAddress ChangeEmailAddress(EmailAddress email)
{
personRepository.ChangeEmail(email);
uow.SaveChanges();
return email;
}
}
// Person Repository
public class PersonRepository
{
// generic repository implementation
}
// Person Entity
public class Person
{
public string Name { get;set; }
public IEnumerable<EmailAddress> EmailAddresses { get;set; }
}
// Email
public class EmailAddress
{
public string Email { get;set; }
public bool IsPrimary { get;set; }
}
無論如何,對此有何看法?
感謝布
好,乾淨,易於理解的問題。:) – 2011-06-16 09:14:38