Repozytorium powinno mieć jedną odpowiedzialność - utrzymywać jeden rodzaj podmiotu. Na przykład. pracowników. Jeśli musisz usunąć niektóre powiązane rekordy z innego repozytorium, wygląda to na logikę biznesową. Na przykład.
Kiedy pracownik jest zwolniony powinniśmy usunąć swój dziennik pracy
i zwyczajowe miejsce dla logiki biznesowej jest to usługi domeny. Usługa ta będzie miała zarówno repozytoriów i wykonać całą pracę:
staffService.Fire(employee)
Wdrożenie będzie wyglądać
public class StaffService
{
private IEmployeeRepository employeeRepository;
private IWorkLogRepository workLogRepository;
private IUnitOfWorkFactory uowFactory;
// inject dependencies
public void Fire(Employee employee)
{
using(var uow = uowFactory.SartNew())
{
workLogRepository.DeleteByEmployee(employee.Id);
employeeRepository.Delete(employee.Id);
uow.Commit();
}
}
}
Więc podstawowy radzi
- starać się utrzymać swoją logikę biznesową w jednym miejscu, nie rozsyłaj jej części do interfejsu użytkownika, części do repozytoriów, części do bazy danych (czasami z powodu problemów z wydajnością, musisz wykonać trochę logiki po stronie bazy danych, ale to jest wyjątek)
- nigdy niech repozytoria odwoływać inne repozytoria, repozytorium jest bardzo komponent niskiego poziomu aplikacji z bardzo prostych zadań
Można zastanawiać się, co zrobić, jeśli masz pracownika i ma pewne zagnieżdżonego obiektu, który jest przechowywany w inna tabela bazy danych. Jeśli używasz tego obiektu oddzielnie od pracownika, wszystko jest jak wyżej - powinieneś mieć oddzielne repozytorium i jakiś inny obiekt (usługę), który manipuluje obydwoma repozytoriami. Ale jeśli nie użyjesz tego zagnieżdżonego obiektu osobno od pracownika, wówczas pracownik jest Korzeniem Aggregate i powinieneś mieć tylko repozytorium pracowników, które będzie sprawdzać obie tabele w środku.
Niesamowita odpowiedź @Sergey to potwierdza moje przemyślenia, rozmawiałem z architektem systemu i zasugerował, że jest cienka linia między tym, czy jest to warstwa biznesowa, czy warstwa danych, ale ponieważ oczyszcza dane, to dobrze jest mieć je w warstwie danych. Mam nadzieję, że uda mi się go przekonać do przeniesienia go do warstwy biznesowej. – MrGrumpy
Reguły usuwania powinny zazwyczaj być ostatecznie spójne, a nie silnie spójne. Ponadto rzadko zdarza się, aby faktycznie nastąpiło fizyczne usunięcie. 'employee.fire() -> EmployeeFired (employeedId) -> EventSubscriber -> ...'. – plalx
Repozytorium nie powinno odwoływać się do innego repozytorium? może, ale przypuśćmy, że mam klasę A, która zawsze potrzebuje zagnieżdżonej klasy B (wymagana do pracy), ale sam obiekt klasy B może działać sam. Gdy moja usługa pobierze obiekt klasy A z repozytoriumA, to repozytorium będzie musiało użyć repozytoriumB, aby ponownie uzyskać objB i przypisać je do obiektu objA (przy użyciu fabryki): 'Repozytorium klasyA { publiczny ClassA GetById (id łańcucha) {objB = repositoryB.GetById (idB); factory.CreateObjA (idA, objB); } } ' Jak należy postąpić, aby uniknąć odniesienia między repozytoriami? – Jonathan