域中的所有实体都需要具有身份。通过继承自DomainEntity
,我能够为类提供身份。
城市域实体(为便于阅读而精简):
public class City : DomainEntity, IAggregateRoot
{
public string Name { get; private set; }
public Coordinate Coordinate { get; private set; }
public City(string name, decimal latitude, decimal longitude)
{
Name = name;
SetLocation(latitude, longitude);
}
public City(string name, decimal latitude, decimal longitude, int id)
: base(id)
{
Name = name;
Coordinate = coordinate;
SetLocation(latitude, longitude);
}
public void SetLocation(decimal latitude, decimal longitude)
{
Coordinate = new Coordinate(latitude, longitude);
}
}
DomainEntity 抽象类:
public abstract class DomainEntity
{
private int? uniqueId;
public int Id
{
get
{
return uniqueId.Value;
}
}
public DomainEntity()
{ }
public DomainEntity(int id)
{
uniqueId = id;
}
}
首次创建新实体时,身份不存在。只有实体被持久化后,身份才会存在。因此,在创建实体的新实例时,Id
不需要提供:
var city = new City("Cape Town", 18.42, -33.92);
当使用 a 从持久性中读取城市时CityRepository
,将使用第二个构造函数来填充标识属性:
public class CityRepository : ICityRepository
{
public City Find(int id)
{
var cityTblEntity = context.Set<CityTbl>().Find(id);
return new City(cityTblEntity.Name, cityTblEntity.Lat, cityTblEntity.Long, cityTblEntity.Id);
}
}
我在这里遇到的问题是我提供了一个可以接受身份的构造函数。这打开了一个洞。我只希望在存储库层中设置身份,但客户端代码现在也可以开始设置Id
值。是什么阻止了某人这样做:
var city = new City("Cape Town", 18.42, -33.92, 99999); // What is 99999? It could even be an existing entity!
如何提供在我的存储库中设置实体身份但从客户端代码中隐藏它的方法?也许我的设计有缺陷。我可以使用工厂来解决这个问题吗?
注意:我知道这不是 DDD 的完美实现,因为实体应该从一开始就具有身份。该Guid
类型将帮助我解决这个问题,但不幸的是我没有那种奢侈。