IoC a Entity Framework rubrika: Programování: .Net
Zdravím,
zaujíma ma ako v aplikačnej vrstve riešite pristup ku Entity Frameworku DB kontextu pomocou IoC kontaineru.
Skúšal som niekoľko postupov, ale žiaden mi nesedel. Hlavne by som chcel mať možnosť explicitne používať kontext v usingu, poprípade ho vnárať a mať možnosť testovať aplikačnú vrstvu.
Moja otázka znie: Ako používate Entity Framework v aplikačnej vrstve a aku abstrakciu nad nim robiť v aplikackcih, v ktorych vyuzivam IoC kontainer?
Co som skusal:
- Datovu vrstvu uplne zakryvajucu EF ako sluzby nad uloziskom dat (ked pouzivam SQL-ko, tak sa mi to osvedcilo, no pri EF to len mapuje a je s tym vela pisania a aplikacna vrtsva mi na mnohych miestach zostala prazdna)
- Injektovanie DB kontextu do sluzieb aplikacnej vrstvy (to je principailne zle)
- Instancovanie DB kontextu v aplikacnej vrstve (clovek sa toho nezbavi a je to netestovatelne)
- Dost som uvazoval o genrickych repozitorys, ale neviem.
-
PS: Nemyslim to tak, ze priamo v APlikacnej vrstve chcem mat navesany EF ale:
Databaza -Entity Framework - nejaka magia - Aplikacna vrtsva - Prezentacna vrstva
Ahoj, odpovím za .net core a svou architekturu.
Předně: napsal jsem si vlastní implementaci Unit of work (aplikovatelné jak pro EF6 tak i EF Core), kterou v mírně pozměněné podobě používáme na aktuálním projektu a na nejspíš půjde i do produkce.
Osobně musím registrovat IDbContextFactory
, DbContextOptions
, UnitOfWork (IUnitOfWorkFactory + IUnitOfWorkManager
) a konečně IRepository<TEntity, TKey>
, kde IRepository je úplně jednoduchý interface
namespace Idea.Repository { public interface IRepository<TEntity, in TKey> : IQueryExecuter<TEntity> { TEntity Find(TKey id); void Create(TEntity entity); void Update(TEntity entity); void Delete(TEntity entity); Task<TEntity> FindAsync(TKey id); Task CreateAsync(TEntity entity); Task UpdateAsync(TEntity entity); Task DeleteAsync(TEntity entity); } }
a na dotazování používám domain queries
namespace Idea.Query.EntityFrameworkCore { public abstract class Query<TEntity, TKey> where TEntity : IEntity<TKey> { protected DbContext Context { get; private set; } protected abstract IQueryable<TEntity> CreateQuery(); public IReadOnlyCollection<TEntity> Execute(IUnitOfWork uow) { // validation + getting DbContext from uow return new ReadOnlyCollection<TEntity>(CreateQuery().ToList()); } } }
S tím, že většina mých aplikací je dělená do vrstev, nejčastěji používám WebApi > Orchestration > Service a samotné service využívají služeb IRepository a Query. Zkoušel jsem na jednom středně velkém projektu Onion architecture a nebylo to úplně špatné.
Důvod proč to takthle dělám je testovatelnost a taky si myslím, že tím, že vystavením Expression<Func<TEntity, TKey>>
pro filtry, ordering, ... přenáším čast logiky na klienta a tím porušuji zapouzdření.
Pro zobrazení všech 4 odpovědí se prosím přihlaste:
Nebo se přihlaste jménem a heslem:
Komentáře