Estou tentando entender como e onde implementar fábricas de modelos de domínio. Incluí meu Companyagregado como uma demonstração de como o fiz.
Eu incluí minhas decisões de design no final - eu gostaria de receber comentários, sugestões e críticas sobre esses pontos.
O Companymodelo de domínio:
public class Company : DomainEntity, IAggregateRoot
{
private string name;
public string Name
{
get
{
return name;
}
private set
{
if (String.IsNullOrWhiteSpace(value))
{
throw new ArgumentOutOfRangeException("Company name cannot be an empty value");
}
name = value;
}
}
internal Company(int id, string name)
{
Name = name;
}
}
A CompanyFactoryfábrica de domínio:
Essa classe é usada para garantir que regras de negócios e invariantes não sejam violados ao criar novas instâncias de modelos de domínio. Ele residiria na camada de domínio.
public class CompanyFactory
{
protected IIdentityFactory<int> IdentityFactory { get; set; }
public CompanyFactory(IIdentityFactory<int> identityFactory)
{
IdentityFactory = identityFactory;
}
public Company CreateNew(string name)
{
var id = IdentityFactory.GenerateIdentity();
return new Company(id, name);
}
public Company CreateExisting(int id, string name)
{
return new Company(id, name);
}
}
O CompanyMappermapeador de entidades:
Essa classe é usada para mapear entre modelos de domínio avançado e entidades de dados do Entity Framework. Ele residiria em camadas de infraestrutura.
public class CompanyMapper : IEntityMapper<Company, CompanyTable>
{
private CompanyFactory factory;
public CompanyMapper(CompanyFactory companyFactory)
{
factory = companyFactory;
}
public Company MapFrom(CompanyTable dataEntity)
{
return DomainEntityFactory.CreateExisting(dataEntity.Id, dataEntity.Name);
}
public CompanyTable MapFrom(Company domainEntity)
{
return new CompanyTable()
{
Id = domainEntity.Id,
Name = domainEntity.Name
};
}
}
O
Companyconstrutor é declarado comointernal.
Razão: Somente a fábrica deve chamar esse construtor.internalgarante que nenhuma outra camada possa instanciar (as camadas são separadas por projetos do VS).O
CompanyFactory.CreateNew(string name)método seria usado ao criar uma nova empresa no sistema.
Razão: Como ainda não teria sido persistida, uma nova identidade exclusiva precisará ser gerada para ela (usando oIIdentityFactory).O
CompanyFactory.CreateExisting(int id, string name)método será usado peloCompanyRepositoryao recuperar itens do banco de dados.
Motivo: o modelo já teria identidade, portanto, isso precisaria ser fornecido à fábrica.O
CompanyMapper.MapFrom(CompanyTable dataEntity)será usado peloCompanyRepositoryao recuperar dados da persistência.
Razão: Aqui, as entidades de dados do Entity Framework precisam ser mapeadas nos modelos de domínio. OCompanyFactoryserá usado para criar o modelo de domínio para garantir que as regras de negócios sejam atendidas.O
CompanyMapper.MapFrom(Company domainEntity)será usadoCompanyRepositoryao adicionar ou atualizar modelos para persistência.
Motivo: Os modelos de domínio precisam ser mapeados diretamente nas propriedades da entidade de dados, para que o Entity Framework possa reconhecer quais alterações devem ser feitas no banco de dados.
obrigado