Digamos que tenhamos um sistema de registro de tarefas, quando uma tarefa é registrada, o usuário especifica uma categoria e a tarefa assume o status 'Excelente'. Suponha, neste caso, que Categoria e Status tenham que ser implementados como entidades. Normalmente eu faria isso:
Camada de aplicação:
public class TaskService
{
//...
public void Add(Guid categoryId, string description)
{
var category = _categoryRepository.GetById(categoryId);
var status = _statusRepository.GetById(Constants.Status.OutstandingId);
var task = Task.Create(category, status, description);
_taskRepository.Save(task);
}
}
Entidade:
public class Task
{
//...
public static void Create(Category category, Status status, string description)
{
return new Task
{
Category = category,
Status = status,
Description = descrtiption
};
}
}
Faço-o assim porque sempre me dizem que as entidades não devem acessar os repositórios, mas faria muito mais sentido para mim se eu fizesse isso:
Entidade:
public class Task
{
//...
public static void Create(Category category, string description)
{
return new Task
{
Category = category,
Status = _statusRepository.GetById(Constants.Status.OutstandingId),
Description = descrtiption
};
}
}
O repositório de status é injetado com segurança de qualquer maneira, portanto, não há dependência real, e isso me parece mais o fato de que é o domínio que está fazendo a decisão que uma tarefa tem como padrão pendente. A versão anterior parece que é o leigo do aplicativo que toma essa decisão. Qualquer um dos motivos pelos quais os contratos de repositório estão frequentemente no domínio, se isso não deveria ser uma possibilidade?
Aqui está um exemplo mais extremo, aqui o domínio decide a urgência:
Entidade:
public class Task
{
//...
public static void Create(Category category, string description)
{
var task = new Task
{
Category = category,
Status = _statusRepository.GetById(Constants.Status.OutstandingId),
Description = descrtiption
};
if(someCondition)
{
if(someValue > anotherValue)
{
task.Urgency = _urgencyRepository.GetById
(Constants.Urgency.UrgentId);
}
else
{
task.Urgency = _urgencyRepository.GetById
(Constants.Urgency.SemiUrgentId);
}
}
else
{
task.Urgency = _urgencyRepository.GetById
(Constants.Urgency.NotId);
}
return task;
}
}
Não há como você desejar passar em todas as versões possíveis do Urgency e não deseja calcular essa lógica de negócios na camada de aplicativos; portanto, certamente essa seria a maneira mais apropriada.
Portanto, esse é um motivo válido para acessar repositórios do domínio?
EDIT: também pode ser o caso de métodos não estáticos:
public class Task
{
//...
public void Update(Category category, string description)
{
Category = category,
Status = _statusRepository.GetById(Constants.Status.OutstandingId),
Description = descrtiption
if(someCondition)
{
if(someValue > anotherValue)
{
Urgency = _urgencyRepository.GetById
(Constants.Urgency.UrgentId);
}
else
{
Urgency = _urgencyRepository.GetById
(Constants.Urgency.SemiUrgentId);
}
}
else
{
Urgency = _urgencyRepository.GetById
(Constants.Urgency.NotId);
}
return task;
}
}