Wypowiedzi
-
Adrian Olszewski:
Zastanowiłbym się tutaj nad sensem takiego uniwersalnego repozytorium. Niemalże pewnym jest, że dla każdego aggregate root'a (wybaczcie angielską nazwę, ale nie znam polskiego odpowiednika) w twojej domenie będziesz musiał zaimplementować dużo bardziej skomplikowaną logikę pobierania i zapisywania obiektów. Przede wszystkim, radziłbym przemyśleć kwestię, które obiekty rzeczywiście potrzebują repozytoriów, a które powinny być obsługiwane razem z innymi obiektami (poleciłbym tutaj książkę Erica Evansa na temat DDD).
W przykładach mam typowe "podręcznikowe" encje: Employee, Store, Product, ale oczywiście w "realu" są inne i jest ich sporo więcej :) i dlatego chcę zautomatyzować tworzenie repozytoriów. Automatyczne tworzenie i dodawanie do locatora dotyczy "standardowych" encji, dla których wystarczy mi standardowy zestaw operacji z IRepository<T>. Oczywiście są także encje bardziej złożone i dotyczące ich repozytoria mają oferować dodatkowe funkcje. Wtedy trzeba je napisać ręcznie (dziedziczą po IRepository<T>) i trzeba je dodać ręcznie do kolekcji w locatorze.
Karim A.:
Podejście takie może rzeczywiście pomóc, ale używane bez umiaru może być równie szkodliwe. Często używane query lepiej wrzucić do repo niż za każdym razem powielać kod zapytania. Oczywiście taka metoda w repo z często używanym query może nadal zwracać IQueryable, aby doprecyzować zapytanie jeśli zajdzie taka potrzeba.
Taka mała uwaga:
W tym projekcie systemu będziesz zmuszony do zmiany kodu repozytorium z prawie każdym nowym typem zapytania. Czy na pewne tego chcesz?
Uważam, że dużo praktyczniejszym pomysłem byłoby udostępnienie swoich obiektów w postaci IQueriable<T> gdzie nowe kryteria lub sposób wyszukiwania danych będą oznaczały tylko inne zapytanie LINQ.
W taki sposób zapewnisz sobie (moim zdaniem) najwyższy poziom elastyczności warstwy DAL.
maciek kański:
W przypadku lazy loading chyba nie ma innej opcji niż virtual na property, bo praktycznie wszystkie tego typu rozwiązania bazują na dynamic proxy. Istnieje również możliwość modyfikacji ILa zaraz po skompilowaniu (np. PostSharp), ale to już zdecydowanie mniej wygodne rozwiązanie, gdyż wymaga dodania odpowiednich targetów do definicji builda. Z kolei modyfikacja ILa w trakcie ładowania dll'ki odpada, bo wymaga zdjęcia podpisu z takiej dll.Remigiusz Cieślak edytował(a) ten post dnia 11.08.10 o godzinie 22:28
Virtual ze względu na NH
Właśnie zapoznałem się ze wsparciem "plain-old" CLR objects w Entity Framework 4.0 i tam się to samo pojawia - aby property obsługiwało lazy loading i/lub change tracking musi być virtual: http://msdn.microsoft.com/en-us/library/dd468057.aspx -
Piotr Głudkowski:
Dają popalić głównie w sytuacjach, gdy są to funkcje niedeterministyczne. Opisana tutaj funkcja byłaby deterministyczna, ponieważ nie odwołuje się do żadnych zewnętrznych obiektów oraz zawsze dla ustalonego zbioru parametrów wejściowych będzie zwracać ten sam wynik. Czy funkcja została zakwalifikowana jako deterministyczna, można łatwo sprawdzić dodając taką funkcję, a następnie uruchamiając zapytanie SELECT SPECIFIC_NAME, SPECIFIC_SCHEMA, IS_DETERMINISTIC FROM INFORMATION_SCHEMA.ROUTINES.
Funkcje zawsze wnoszą narzut związany z wywołaniem, poza tym czasem potrafią dać popalić optymalizatorowi :)