Micro ORM ale nie chodzi tu o semantykę, tylko zmianę technologii używanej do persystencji modelu domenowego. Problem Dappera jest taki, że nie lubi się bardzo z prywatnymi polami i setterami. W przypadku, gdy tak jak piszesz masz bogatą domenę z wieloma typami a nie tylko proste stringi i inty to zaczyna się czarowanie żeby to ręcznie poskładać.
Nie o semantykę chodzi, tylko jeśli coś z definicji nie nadaje się do czegoś, to trudno wymagać, aby mogło zastępować coś, co jest od tego czegoś lepsze.
Wystarczy sobie popatrzeć jak obsługiwana jest współbierzność w NHibernate i EF Core, żeby zobaczyć, że zmiana z jednego na drugi wymaga zmiany typu pola na modelu. Do tego EF Core wciąż ma problem z inicjowaniem prywatnych backing fields jak kolekcje przy włączonym lazy loadingu i potem żeby coś sprawdzić na kolekcji (jakiś niezmiennik) robić hacki w postaci items.Count
żeby zainicjować kolekcję. Jak się pisze TODO listę to faktycznie zmiana z A na B będzie trywialna, ale przy złożonych domenach, gdzie chcemy enkapsulować logikę na poziomie modelu już nie będzie tak prosto żeby zmienić A na B
Czyli EF się nie nadaje do mapowania obiektowej domeny.
Robienie takiej samej abstrakcji na swojej bazie danych w większości sytuacji nie ma sensu bo czas pracy włożony w utworzenie takiej ACL i jej utrzymywanie w czasie tylko dlatego że może za 3 lub 4 lata zmienimy SQL Server na Mongo albo Cassandre jest nieuzasadnionym kosztem. Ale to moje zdanie i nie trzeba się z nim zgadzać :P
W ogóle nie rozpatruję kwestii zmiany bazy danych ani ORMa, jedynie efektywne połączenie bogatej domeny z bazą nieobiektową.
Jeśli mamy obiektową, poprawnie enkapsulowaną domenę implementującą logikę biznesową, to mamy dwie możliwości:
- Walczymy z ORMem, aby ją zmapować, prawdopodobnie się nie udaje, więc trzeba brudzić kod domenowy tak, aby ORM go zaczął ogarniać. Do tego powstają jakieś pluginy/rozszerzenia/customizacje do ORMa mające pohackować to, czego jego twórcy nie przewidzieli. Na końcu i tak wyjeżdża Microsoft cały na czarno, ze stwierdzeniem, że liczby zmiennoprzecinkowe będą ucinane zamiast zaokrąglane do precyzji, bo to jest błąd, ale bardzo stary i dużo kodu od niego zależy, więc nie będą naprawiać.
- Dodajemy oddzielny model składowania, i repozytoria (które i tak mamy), mapują na ten model, który jest zaprojektowany tak, że ORM go rozumie z łatwością.
Sposób 2 jest banalny do implementacji, w praktyce (w rzeczywistym projekcie, nie przykładzie z bloga) może nawet będzie miał mniej kodu (bo jednolijkowe DTO dla repozytoriów zajmą raczej mniej kodu niż niż wszystkie dzikie obejścia i haki na konfigurację ORMa razem wzięte), a przede wszystkim zajmie mniej czasu, bo hackowanie to długotrwały proces w porównaniu do pisania prostych DTO.
Oczywiście powód do chwały mniejszy, bo każdy przecież chce być hakierem w świecie spaghetti.
Typowy przypadek w typowej polskiej plantacji spaghetti zwanej dla niepoznaki software house nie jest żadnym z powyższych, bo tam się nie stosuje ani metod w "encjach", za to ORMy są owrapowane co najmniej w repozytoria (bo i wrapper na ORM się zdarza, "na wszelki wypadek"), no i to wszystko to oczywiście strata czasu, ale o tym już pisałem wiele razy, i nie chcę więcej; nie jest to problem, który rozważam teraz.
No to chyba masz bardzo stare informacje. W EfCore można już obecnie wszystko skonfigurować zewnętrznie a nawet wiecej niż na atrybutach. Powiąznia n do n bez klasy pośredniej również działaja i to nawet by convetion, oczywiście można je dodatkowo skonfigurować. Nie musimy mieć nawet żadnych publicznych seterów.
To super, że mają już to, co konkurencja 15 lat temu.
Tylko ja tu raz czytam, że EFCore umie, raz że nie umie - pogubić się można w tych zmianach zeznań. :P
Architekturę wybierasz pod zespół a nie na odwrót. Nie da się bo takie zespoly które to ogarną to rzadkość i ryzyka zafiksowania się na dostawce. Nawet jak już jakimś cudem znajdzie się magik co to ogarnie w zespole to będzie długie i drogie bo trzeba resztę zespołu „nauczyć”. Ostatnie jest podsumowanie.
Skoro tak nam zależy na prostocie, to czemu zatem nie wybrać prostszego rozwiązania (nr 2 z mojej listy)?
A tak poza tym, to jeszcze nie spotkałem się z wybieraniem architektury pod zespół. Pod problem czasem tak, zazwyczaj pod organizację, ale jeszcze nigdy pod zespół.
Pod zespół mógłby wybrać co najwyżej sam zespół, ale nie jakiś ktoś z zewnątrz zespołu, kto przecież tego zespołu nie zna.
Rozumiem ze z własnej kieszeni pokryjesz ten pp ? Bo jak nie to musisz na starcie końcowa estymate mnożyć raz 2-6 w zależności od wielkości zespołu. Przez co twoja oferta jest niekonkurencyjna ergo firma nie dostaje projektu.
Nie tak działa pair programming. Ale jeśli chodzi o konkurowanie kosztami, to dyskusja nie dotyczy jakości, bo z niej się świadomie rezygnuje.
obiekt biznesowy który w konstruktorze przyjmie ten obiekt ORM owy i ustawi sobie w metodzie incijalizujacej poprawny stan tak?
To jest raczej słaby pomysł, niech konstruktor przyjmuje proste wartości (nie chodzi o to, że tylko string
i int
, po prostu nie typy z zewnętrznych warstw).
Jest jeszcze druga opcja że proponujesz mapowanie z jednego na drugie w jakimś factory no ale wtedy sorry bo mamy klasy biznesowe które muszą mieć PUBLICZNE setery żeby dało się je zmapowac więc możemy utworzyć obiekt biznesowy w niepoprawnym stanie co dalej kończy się porażka enkapsulacji.
Można użyć bibliotek, które nie mają takich perwersyjnych ograniczeń w mapowaniu.