Обычно я использую nHibernate для создания уникальных идентификаторов для своих сущностей... но я думаю о создании их в коде? Рассмотрим следующий пример: (Если я делаю что-то еще неправильно, укажите на это, так как я новичок в DDD):
Это все классы, которые принадлежат одной сборке, то есть моей модели предметной области.
public interface AggregateRootState
{
bool CanAddChild();
bool CanModifyChild();
bool CanDeleteChild();
}
public class AggregateRoot
{
private AggregateRootState aggregateRootState;
public IList<ChildEntity> ChildEntityList {get; internal set;}
public bool CanAddChild()
{
return aggregateRootState.CanAddChild();
}
public void AddChild(ChildEntityParameters childEntityParameters)
{
if (!CanAddChild())
throw new NotImplementedException("aggregate root not in correct state.");
ChildFactory.CreateChildEntity(childEntityParameters);
}
public bool CanModifyChild()
{
return aggregateRootState.CanModifyChild();
}
public void ModifyChild(ChildEntityParameters childEntityParameters)
{
if (!CanModifyChild())
throw new NotImplementedException("aggregate root not in correct state.");
ChildEntity childEntity = ChildEntityList.First(c => c.Id == childEntityParameters.Id);
childEntity.Property1 = childEntityParameters.Property1;
childEntity.Property2 = childEntityParameters.Property2;
}
public bool CanDeleteChild()
{
return aggregateRootState.CanDeleteChild();
}
public void DeleteChild(Guid Id)
{
if (!CanDeleteChild())
throw new NotImplementedException("aggregate root not in correct state");
ChildEntityList.Remove(ChildEntityList.First(c => c.Id == Id));
}
public void Validate()
{
//code to validate the object and ensure it is in a savable state.
}
}
public class ChildEntityParameters
{
public Guid Id {get; set;}
public string Property1 {get; set;}
public string Property2 {get; set;}
}
public class ChildEntity
{
internal ChildEntity() { }
public Guid Id {get; set;}
public string Property1 {get; internal set;}
public string Property2 {get; internal set;}
}
internal static class ChildFactory
{
public static void CreateChildEntity(ChildEntityParameters childEntityParameters)
{
ChildEntity childEntity = new ChildEntity();
childEntity.Property1 = childEntityParameters.Property1;
childEntity.Property2 = childEntityParameters.Property2;
}
}
Тогда мой сервисный уровень будет выглядеть примерно так:
//for simplicity I have arguments rather than using the request / response pattern.
public class ServiceLayer
{
public void AddChildEntity(Guid aggregateRootId, string string1, string string2)
{
AggregateRoot aggregateRoot = aggregateRootRepository.FindBy(aggregateRootId);
ChildEntityParameters childEntityParameters = new ChildEntityParameters();
childEntityParameters.Property1 = string1;
childEntityParameters.Property2 = string2;
aggregateRoot.AddChild(childEntityParameters);
aggregateRoot.Validate(); //will throw exception if there is something wrong.
aggregateRootRepository.Save(aggregateRoot);
}
}
Теперь все это работает хорошо и хорошо. Однако проблема в том, что если я хочу вернуть идентификатор вновь созданного ChildEntity на уровень представления? В настоящее время это невозможно. Мне пришлось бы вернуть весь граф объектов. Единственная альтернатива, о которой я могу думать, - это внести следующие изменения в мой код:
internal static class ChildFactory
{
public static void CreateChildEntity(ChildEntityParameters childEntityParameters)
{
ChildEntity childEntity = new ChildEntity();
**childEntity.Id = Guid.NewGuid();**
childEntity.Property1 = childEntityParameters.Property1;
childEntity.Property2 = childEntityParameters.Property2;
}
}
public class ServiceLayer
{
public **Guid** AddChildEntity(Guid aggregateRootId, string string1, string string2)
{
**Guid Id;**
AggregateRoot aggregateRoot = aggregateRootRepository.FindBy(aggregateRootId);
ChildEntityParameters childEntityParameters = new ChildEntityParameters();
childEntityParameters.Property1 = string1;
childEntityParameters.Property2 = string2;
**Id = aggregateRoot.AddChild(childEntityParameters);**
aggregateRoot.Validate(); //will throw exception if there is something wrong.
aggregateRootRepository.Save(aggregateRoot);
return Id;
}
}
Это неправильно? или все нормально? Было бы хорошо, если бы кто-нибудь разъяснил!