/ / Zasady SOLID, wzorzec repozytorium i pamięć podręczna EntityFramework w Asp Net Mvc - .net, asp.net-mvc, framework-encja, wzorzec repozytorium, solid-rules

Zasady SOLID, wzorzec Repozytorium i pamięć podręczna EntityFramework w Asp Net Mvc - .net, asp.net-mvc, framework-entity, wzorzec repozytorium, zasady stałe

Mam rozwiązanie studia wizualnego przy użyciu bryływzór. Mam IRepository (implementacja Crud), IDbFactory (używane przez repozytorium), IUnitOfWork. Mam również usługi, które używają repozytoriów do tworzenia niestandardowych zapytań i skomplikowanej operacji na bazie danych. Używam również wzoru IoC z Ninject. W internetowym kontrolerze mvc korzystam tylko z usług dostępu do bazy danych. Repozytorium otrzymuje IDbFactory, który buduje kontekst EntityFramework. Mam pewne problemy:

  • W serwisie, gdy muszę uzyskać dostęp do dwóch tabeldo przyłączenia się do nich powinienem użyć dwóch repozytoriów, wywołując metodę GetAll () obu z nich. W takim przypadku oba repozytoria powinny mieć ten sam kontekst EntityFramework.
  • Poprzedni przypadek wskazuje mi, że DbContext powinien być współdzielony przez wszystkie repozytoria, dzięki czemu mogę dołączyć do IQueryables w usłudze z różnych repozytoriów.
  • Aby osiągnąć ten cel, skonfigurowałem w kontenerze IoC, DbContext w zakresie singleton. Dlatego każde repozytorium ma ten sam DbContext.
  • Problem z tym rozwiązaniem polega na tym, żeDbContext ma pamięć podręczną. Tak więc, gdy proces zewnętrzny (inny niż projekt sieciowy) zmienia moje dane, DbContext nie zdaje sobie z tego sprawy, a projekt sieciowy czasami nie wyświetla prawdziwych danych.
  • Czytam o zniszczeniu DbContext w każdym wywołaniu repozytorium, ale nie mogę tego zrobić, ponieważ każde repozytorium powinno używać tego samego DbContext

Czy coś jest nie tak z moją strukturą projektu? Czy muszę to naprawić w warstwie repozytorium? Co mam robić? Projekt jest w fazie rozwoju, więc mogę zmienić architekturę dostępu do danych. Lubię używać IQueryables w kontrolerze, więc filtry użytkowników w siatkach danych generują zapytania SQL.

Odpowiedzi:

4 dla odpowiedzi № 1

Jeśli chodzi o podany tutaj problem, jestnic złego w strukturze projektu. Problem wynika z używania lunety Singleton. Zamiast tego powinieneś używać zakresu Żądania dla aplikacji internetowej. Zapewnia to otrzymanie nowego kontekstu przy każdym żądaniu, dzięki czemu nie będą zachodzić na siebie różne żądania, a nawet różni klienci, co może być wyjątkowo niebezpieczne.

To powiedziawszy, twoja struktura projektu jestprzekombinowane. Repozytorium / wzorce jednostek pracy są przeznaczone do dostępu do danych na niskim poziomie. ORM, podobnie jak Entity Framework, obsługuje to wszystko, aw rzeczywistości Entity Framework już implementuje te wzorce. The DbContext to jednostka pracy i każda DbSet jest repozytorium. Dodanie własnego repozytorium / jednostki warstwy roboczej jest zbędne i niepotrzebne. Twoje usługi powinny bezpośrednio wykorzystywać kontekst Entity Framework. Nawet wtedy posiadanie wielu usług jest prawdopodobnie niepotrzebne, w zależności od tego, co robią. Jeśli wszystkie działają z tym samym źródłem danych (tj. Kontekstem Entity Framework), a zwłaszcza jeśli wszystkie działają z podobnie W kontekście Entity Framework wszystkie powinny być naprawdę połączone w jedno.

W moich osobistych projektach wykorzystuję jedenKlasa „service” z metodami ogólnymi dla unikalnej instancji kontekstu. Metody ogólne pozwalają mi pracować z dowolną jednostką należącą do tego kontekstu bez konieczności odnawiania dodatkowych instancji klasy „service”. Dzięki zapewnieniu, że wszystko implementuje jeden lub więcej interfejsów i zastosowaniu wstrzykiwania zależności w celu spełnienia ograniczeń interfejsu, podstawowa warstwa danych jest całkowicie uwzględniana. mam seria postów które są bardziej szczegółowe, jeśli jesteś zainteresowany.

Mówię to wszystko, ponieważ wydaje się, że „nadmiernie koncentrujesz się na wzorach i„ najlepszych praktykach ” przewodniki. „Oni lubią koła treningowe na rowerze.” Wszystkie oparte są na różnych zasadach dobrego projektowania kodu. Dowiedz się i zastosuj zasady i nie martw się sprawdzaniem wszystkich pól na jakiejś liście wzorców projektowych.

Co ciekawe, rdzeń Stack Overflowpodstawa kodu faktycznie unika wielu wzorców (nawet wstrzykiwania zależności), ponieważ „koncentrują się one laserowo na surowej wydajności, a niektóre wzorce projektowe, gdy są stosowane, faktycznie utrudniają wydajność. Chodzi o to, że sposób projektowania aplikacji powinien być oparty na potrzebach konkretnej aplikacji. Wzory projektowe powinny być stosowane tylko w takim stopniu, w jakim są one zgodne z potrzebami aplikacji, nie tylko dlatego, że uważasz, że powinieneś.


0 dla odpowiedzi nr 2

Przede wszystkim cykl życia DbContextpowinien trwać dla całej jednostki biznesowej, w aplikacjach MVC jest to zgodne z HttpRequest. Zapewnia transakcję od początku wysyłania żądania otrzymania odpowiedzi przez użytkownika.

Po drugie, nie powinieneś mieć GetAll() funkcja w repozytorium podstawowym. To bardzo złe rozwiązanie, które może mieć wpływ na wydajność twojej aplikacji. Powinieneś utworzyć funkcję jak: GetByQuery(Func<T, bool> whereQuery, int skip, int take) gdzie T jest ogólnym typem klasy jednostek. Alternatywnie możesz dodać parametr do sortowania.

Może powinieneś pomyśleć o rezygnacji zWzór repozytorium? Jak duży jest twój projekt? Czy w przyszłości można zmienić sposób przechowywania danych? Jeśli nie, możesz bezpośrednio obsługiwać DbContext w swoich usługach. Entity Framework to rodzaj implementacji wzorca repozytorium i UnitOfWork.