Supponiamo di avere un sistema di registrazione delle attività, quando un'attività viene registrata, l'utente specifica una categoria e l'attività passa automaticamente allo stato "Eccezionale". Supponiamo in questo caso che Categoria e Stato debbano essere implementati come entità. Normalmente farei questo:
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 in questo modo perché mi viene costantemente detto che le entità non dovrebbero accedere ai repository, ma avrebbe molto più senso per me se lo facessi:
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 stato viene comunque iniettato dipendenza, quindi non esiste una reale dipendenza, e questo mi sembra più simile al dominio che sta prendendo la decisione che un'attività viene impostata automaticamente come eccezionale. La versione precedente sembra essere il livello dell'applicazione che prende quella decisione. Qual è il motivo per cui i contratti di deposito 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 in cui vorresti passare in tutte le possibili versioni di Urgency e in nessun modo vorresti calcolare questa logica di business nel livello dell'applicazione, quindi sicuramente questo sarebbe il modo più appropriato?
Quindi questo è un motivo valido per accedere ai repository dal dominio?
EDIT: questo potrebbe anche essere il caso di 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;
}
}