WebForms - pristup k EF contextu   zodpovězená otázka

ASP.NET WebForms, Entity Framework, Architektura

Ahoj,

resim nejaky univerzalni pristup k EF contextu (code first) z webforms aplikace a nevim, zda nejdu spatnym smerem.

Zatim jsem si udelal statickou tridu "PerRequestContext", ktera pri dotazu na .Current inicializuje EF DbContext, ulozi jej do HttpContext.Current.Items a umoznuje tedy kdekoliv v aplikaci volat "PerRequestContext.Current", ktera vraci otevreny DbContext v prubehu jednoho requestu.

V global.asax na Application_EndRequest je pak volan PerRequestContext.Dispose, ktery ten DbContext zase zrusi (a pripadne by mohl i volat db.SaveChanges() )

Je to rozumny postup, nebo v pozdejsi fazi narazim na nejake zasadni uskali, proc to takto nedelat? Jak to delate vy?

Diky za nazor.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Já bych DbContext nikde nedržel a vždy ho vytvářel až v metodách, které potřebují přistoupit k datum (ideálně v using bloku).

Pokud potřebujete DbContext vytvořit nějakým "složitějším" kódem než je jen volání výchozího konstruktoru, tak je doporučovaný způsob udělat si na to Factory třídu (nebo můžete případně použít nějaký DI kontejner), aby byl tento kód jen na jednom místě.

Koukněte se např. na tento článek:

http://www.dotnetportal.cz/blogy/3/Tomas...

nahlásit spamnahlásit spam 1 / 3 odpovědětodpovědět

Diky za reakci.

Nevim, zda nejdu uplne spatnym smerem, ale ten DbContext bych rad inicializoval jednou, aby napr. v Application_PostAuthenticateRequest slo ziskat zivou attached entitu prihlaseneho uzivatele a mit moznost s ni pak pracovat v metodach jednotlivych stranek. Napr. ji priradit ke vzniklemu zaznamu, nebo pristupovat k jejim (lazy) kolekcim atp... Ta entita uzivatele je nutna nacitat pred kazdou strankou i kvuli overovani, zda stale trvaji nejaka pristupova prava atp.

Na druhou stranu ten projekt neni tak velky, aby muselo vznikat vice vrstev (Repository patern atp.) a zaroven se v nem do budoucna nic moc nebude menit, aby bylo nutne vse oddelit do nezavislych bloku a cele to komplikovat nutnosti Interfaces ke vsemu.

Tedy otazka je spise zda je nejaka rozumna cesta na pulce cesty mezi using(dbContext) v kazde metode a ponoreni (v mem pripade mozna utopeni) se do IoC/DI apod.?

S tim http requestem v global.asax mi to prislo takove jednoduche, ale nejsem si jist, zda to neni prilis jednoduche a v budoucnu s tim nenarazim na neco, co mi nyni unika.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Co se týče držení identity uživatele, až už za účelem zjištění nějakých údajů či ověřování práv, na to se mi osvědčilo použití WIF (Windows Identity Foundation), kde si lze do identity v podobě claims uložit vše co je potřeba. SessionAuthenticationModule pak zajišťuje, že jsou tyto údaje serializované do cookie a při každém requestu opět obnovené a k dispozici.

Koukněte na můj článek zde:

http://blog.imp.cz/post/2012/05/15/Windo...

A pokud potřebujete někam uložit vazbu na aktuálního uživatele, tak tam stačí nastavit jeho ID (které bude v claims) a není potřeba mít načtenou celou entitu.

"zaroven se v nem do budoucna nic moc nebude menit" z praxických zkušeností vám každý řekne, že toto neplatí v žádném projektu. To ale samozřejmě neznamená, že byste se bez Repository a IoC/DI neobešel.

Pokud byste opravdu šel cestou držení DbContextu pro request (např. v HttpContext.Items), musíte nějakým způsobem zajistit jeho uvolňování na konci zpracování requestu. Windsor Castle má tuším typ životnosti per request, která toto řeší, to je jedna z variant. Jinak si to budete muset napsat a zajistit sám.

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět

Ok, diky. Zkusim se trochu vic porozhlednout po lifetime moznostech u IoC. Prijde mi ale, ze nepotrebuji zadnou extra modularni funkcnost, kterou to reseni prinasi (naopak si myslim, ze logicky vytvoreni dbContextu na zacatku requestu a jeho zruseni na konci by mela byt nejprimejsi a nejrychlejsi cesta toho, co napr. Windsor Castle stejne udela, akorat ze to ma prolozene nekolika abstraktnimi vrstvami a rezii s instancovanim.

Kdyz ale zminujete WIF, jeste bych se rad zeptal na jednu vec. Zmineny clanek jsem pred casem objevil a na jeho zaklade se do WIF pustil (diky za nej!). Prakticky to ale zpusobilo, ze vygenerovana cookie mela takovou velikost, kterou by mi svedomi nedovolilo pouzit. Do ClaimsIdentity, ktera se serializuje do cookie tedy ukladam pouze username a userId (i presto ma pomerne znacnou velikost) a zbytek claimsu (i hodne roli) pridam az do deserializovane identity, v Authenticate requestu. V te identite to pak vydrzi pocas session? (SessionAuthenticationModule) Nebo hrozi, ze se deserializace z cookie provede opet i nekdy drive? Mam toto resit v Application_PostAuthenticate nejakou kontrolou, zda identita ma jiz nactene role (a pokud ne, tak doplnit)? Neni na to nekde vhodnejsi misto? ... Neni take problematicke, kdyz se do claimsu ulozi role a mezitim je uzivateli zmenime? Deserializuje se pak nejake historicke udaje (dokud je dotycny navstevnik prihlaseny). Nenapadlo me, jak toto obejit.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To je samozřejmě pravda, že by tam mělo být údajů co nejméně, aby nebylo cookie zbytečné velké.

Moje zkušenost je taková, že pokud se jedná o menší aplikaci, která má cca do 20-ti rolí, tak uložit do claims id uživatele, jeho jméno pro zobrazování, ty role a případně něco málo dalšího by mělo být ještě ok. SessionAuthenticationModule také dělá to, že pokud by bylo cookie moc velké tak údaje automaticky rozloží do více cookie.

Samozřejmě závisí na scénáři, pokud např. potřebujete, aby byla aplikace rychlá i na mobilu připojeného přes pomalá data, tak to bude hrát roli větší.

Pro případy, kdy by bylo cookie moc velké, lze ve WIF postupovat tak, že se do claims dá opravdu jen to userID a při každém requestu se provádí tzv. claims transformation tj. že se podle ID z databáze dotáhnou ostatní údaje (a role).

Koukněte se na ClaimsAuthenticationManager:

http://msdn.microsoft.com/en-us/library/...

Jednoduchý příklad byl také zde:

http://wug.cz/praha/akce/521-Autentifika...

(viz ClaimsTransformation.zip).

Pokud by vadil ten jeden dotaz do db pro každý request, tak je to potřeba na základě toho ID nějak cachovat. Před přihlášením uživatele je možné pro dané ID cache vyprázdnit, aby uživatel dostal platná data. To, že se po změně práv musí uživatel odhlásil a znovu přihlásit většinou tolik nevadí.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback