Supponiamo di avere un sistema di registrazione delle attività, quando viene registrata un'attività, l'utente specifica una categoria e l'attività è impostata su "Eccezionale". Supponiamo in questa istanza che Categoria e Stato debbano essere implementati come entità. Normalmente lo farei:
Livello applicazione:
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
};
}
}
Lo faccio così perché mi viene costantemente detto che le entità non dovrebbero accedere ai repository, ma sarebbe molto più sensato per me se facessi questo:
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
};
}
}
Il repository di status è comunque iniettato in dipendenza, quindi non c'è una reale dipendenza, e questo mi sembra più che il dominio che sta facendo la decisione che un task sia in sospeso. La versione precedente sembra essere il lay-out dell'applicazione che prende questa decisione. Qual è il motivo per cui i contratti di repository sono spesso nel dominio se questo non dovrebbe essere una possibilità?
Ecco un esempio più estremo, qui il dominio decide l'urgenza:
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;
}
}
Non c'è modo che tu voglia passare in tutte le possibili versioni di Urgency e in nessun modo vorresti calcolare questa logica di business nel livello applicazione, quindi sicuramente questo sarebbe il modo più appropriato?
Quindi questo è un motivo valido per accedere ai repository dal dominio?
EDIT: potrebbe essere il caso anche per i metodi non statici:
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;
}
}