Supposons que nous ayons un système de journalisation des tâches, lorsqu'une tâche est journalisée, l'utilisateur spécifie une catégorie et la tâche par défaut a le statut 'En suspens'. Supposons dans ce cas que la catégorie et le statut doivent être implémentés en tant qu'entités. Normalement, je ferais ceci:
Couche d'application:
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);
}
}
Entité:
public class Task
{
//...
public static void Create(Category category, Status status, string description)
{
return new Task
{
Category = category,
Status = status,
Description = descrtiption
};
}
}
Je le fais comme ça, car on me dit constamment que les entités ne devraient pas accéder aux référentiels, mais il serait beaucoup plus logique pour moi de le faire:
Entité:
public class Task
{
//...
public static void Create(Category category, string description)
{
return new Task
{
Category = category,
Status = _statusRepository.GetById(Constants.Status.OutstandingId),
Description = descrtiption
};
}
}
Le référentiel de statuts est de toute façon injecté dans la dépendance, donc il n'y a pas de réelle dépendance, et cela me semble davantage que c'est le domaine qui prend la décision qu'une tâche par défaut est en suspens. La version précédente donne l'impression que c'est le calque d'application qui prend cette décision. Pourquoi les contrats de référentiel sont-ils souvent dans le domaine si cela ne devrait pas être possible?
Voici un exemple plus extrême, ici le domaine décide de l'urgence:
Entité:
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;
}
}
Il n'y a aucun moyen que vous souhaitiez passer dans toutes les versions possibles d'Urgence, et aucun moyen que vous ne souhaitiez calculer cette logique métier dans la couche application, alors ce serait sûrement le moyen le plus approprié?
Est-ce donc une raison valable pour accéder aux référentiels à partir du domaine?
EDIT: Cela pourrait également être le cas sur les méthodes non statiques:
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;
}
}