Все объекты в домене должны иметь личность. Наследуя от 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);
Когда города считываются с сохранением с помощью 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
поможет мне решить эту проблему, но к сожалению, у меня нет этой роскоши.
Если это приемлемо, вы можете оставить это до ORM? Я сам не являюсь участником Framework Framework, но с NHibernate вы можете выбрать сопоставление столбца (идентификатор в вашем случае) с частным полем, а затем предоставить свойство для чтения только для чтения. Кажется, есть аналогичный вариант в Entity Framework: http://blog.oneunicorn.com/2012/03/26/code-first-data-annotations-on-non-public-properties/ – lasseeskildsen