rtl*_*ell 10 c# persistence domain-driven-design repository-pattern
我很好奇人们的想法是将DAL实体的Id保留为域实体的属性,绝对是最只读的属性.
我的第一个想法是这样做是可以的,但我想的越多,我就越不喜欢这个主意.在所有域模型应该完全不知道数据如何持久化之后,每个域模型上的保持和Id属性是一个不太微妙的指示.持久层可以是不需要主键的东西,或者在域模型中暴露的另一个属性可以是用于识别的合适候选者,模型号.也许.
但是那让我想到,对于那些没有可靠的方法来唯一识别数据库持久层中的条目的域模型,它们在更新或删除时如何识别条目?
基于弱引用键的字典可以做到这一点; WeakDictionary<DomainEntity, PrimaryKeyType>.只要存储库的客户端Fetch是DomainEntity对实体及其持久层Id的弱引用的集合存储在此内部字典中,然后何时将修改后的实体返回到该内部字典,该字典将成为存储库实现的一部分.用于更新持久层的存储库,可以执行以下操作来获取Id
PrimaryKeyType id = default(PrimaryKeyType);
if (!weakDictionary.TryGetValue(someDomainEntity, out id))
// id not found, throw exception? custom or otherwise..
// id found, continue happily mapping domain model back to data model.
Run Code Online (Sandbox Code Playgroud)
我认为这种方法的好处是,域实体不需要维护其持久层特定的ID,并且存储库强制您通过某种Fetch...方法或Add/CreateNew方法调用获得合法的域实体,否则您应该尝试更新/删除它将引发异常的实体.
我知道这可能是过度工程化的,我应该紧缩并务实,我只是好奇其他人对此的看法.
我不想为这个小问题启动另一个线程,因为它有点相关.但是因为它是最近我开始研究DDD(虽然在这种情况下我的数据库是第一个)我想知道我是否可以确认我对域实体有正确的心态,这是我的员工域实体的一个减少的例子.
public class Employee : DomainEntity
{
public string FirstName { get; }
public string LastName { get; }
public UserGroup Group { get; }
// etc..
// only construct valid employees
public Employee(string firstName, string lastName, SecureString password, UserGroup group);
// validate, update. (not sure about this one.. pulled it
// from an open source project, I think that names should be able to be set individually).
AssignName(string firstName, string lastName);
// validate, update.
ResetPassword(SecureString oldPassword, SecureString newPassword);
// etc..
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
您使用弱引用的提议有一个主要缺陷。
\n\n您可能知道,领域实体有一个重要特征,即它们必须具有身份。出于比较的原因,这一点很重要。如果两个实体具有相同的身份,无论其属性值如何,则它们被视为相等:
\n\nEntity1 == Entity2 \xe2\x87\x94 Entity1.Identity == Entity2.Identity\nRun Code Online (Sandbox Code Playgroud)\n\n典型的“设计模式”是从DomainEntity<T>抽象类继承所有实体,该抽象类覆盖这些对象的比较并按标识进行比较。
现在,考虑使用弱引用查找的方法。让我们举个例子:
\n\n您Entity1从存储库中获取“Reegan Layzell”用户。然后,您再次从存储库中获取完全相同的“Reegan Layzell”实体作为Entity2。现在,您的域中的两个对象具有相同的实体。但他们有不同的参考(当然)。
比较时,这些实体在您的域中不会被视为相等。
\n\n我钦佩您对将数据库问题引入领域模型的恐惧,但是将数据库 ID 传播到您的实体中几乎不会影响模型的质量,而且会为您省去很多麻烦。正如你所说,我们需要务实。
\n\n关于你的Employee例子:AssignName真的有道理吗?事实上,员工的名字在创建后真的可以改变吗?除此之外,看起来你的想法是正确的。我强烈建议您观看: Jimmy Bogard 的《Crafting Wicked Domain Models》。