Załóżmy, że mamy system rejestrowania zadań. Gdy zadanie jest rejestrowane, użytkownik określa kategorię, a zadanie domyślnie ma status „Zaległy”. Załóżmy w tym przypadku, że kategorię i status należy zaimplementować jako byty. Normalnie zrobiłbym to:
Warstwa aplikacji:
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);
}
}
Jednostka:
public class Task
{
//...
public static void Create(Category category, Status status, string description)
{
return new Task
{
Category = category,
Status = status,
Description = descrtiption
};
}
}
Robię to w ten sposób, ponieważ konsekwentnie mówi mi się, że podmioty nie powinny uzyskiwać dostępu do repozytoriów, ale byłoby to dla mnie znacznie rozsądniejsze, gdybym to zrobił:
Jednostka:
public class Task
{
//...
public static void Create(Category category, string description)
{
return new Task
{
Category = category,
Status = _statusRepository.GetById(Constants.Status.OutstandingId),
Description = descrtiption
};
}
}
Repozytorium statusu i tak jest wstrzykiwane zależnie, więc nie ma żadnej rzeczywistej zależności, a to wydaje mi się bardziej, że to domena decyduje, że zadanie domyślnie zalega. Poprzednia wersja wydawała się być warstwową aplikacją podejmującą tę decyzję. Jakieś powody, dla których umowy repozytorium są często w domenie, jeśli nie powinno to być możliwe?
Oto bardziej ekstremalny przykład, tutaj domena decyduje o pilności:
Jednostka:
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;
}
}
Nie ma możliwości, abyś przeszedł we wszystkie możliwe wersje Pilności, i nie ma możliwości obliczenia tej logiki biznesowej w warstwie aplikacji, więc na pewno byłby to najbardziej odpowiedni sposób?
Czy to jest ważny powód, aby uzyskać dostęp do repozytoriów z domeny?
EDYCJA: Może tak być również w przypadku metod niestatycznych:
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;
}
}