Diskuze: Architektura ASP.NET MVC, reference
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 20 zpráv z 20.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Píšeš to krapet zmateně (nebo to možná jen já neumím z toho vyčíst), ale když se podíváš na tutoriál http://www.itnetwork.cz/…t/mvc-e-shop určitě tam (myslím, že hned v prvním dílu) najdeš odpověď...
Repa, Queries, Commandy by nemeli v BL co delat. Zalezi take jestli mas anemicky, ci RDM model. Tak jako tak, v BL máš buďto servisy (někdo tomu říká Managery, někdo UI fasády) - takto je tomu u Anemického modelu. Nebo tam máš byznys doménové modely u RDM.
Repositories, Queries i Commandy by mely být v DALu - jedná se totiž o abstrakci přístupu k datum.
Hmm, ani i to uz nedovoli opravit gramatickou chybu...
Pokud dáte Query objecty,Commandy a Repa do BL, znamená to právě nejčastěji referenci knihoven čistě pro přístup k datum - už to by vám mělo naznačit, že to nemá v BL moc co dělat Je to ale jedno.. beztak z tech veci vracíte IQueryable, takže to pravděpodobně máte blbě celé
proc?:D kdybych mel blbej den, tak povim jen, ze jsou blbky ted se snazim pomoci a ocekavam dotaz, proc je vracet iqueryable spatne a proc by to cele nemelo byt v BL
Jinak ViewModely bych dal do Webového projektu klidně, většinou ¨se v jiných vrstvách než WEB nepohybují, leda by jste měli nějaký tag-based caching s invalidací na základě tagu.
No ode mne se ho nedočkáš ono to ani není moc k tématu tbh
Ahoj, tak tedy proč je vracení IQueryable špatné? Důvod, proč mám v tom návrhu Queries, Commands a Repositories v BLL vrstvě je ten, že jsem to viděl jednak na WUG ve videu T. Hercega Zajímavé návrhové vzory a pak také v příkladech na netu. Přišlo mi ale zvláštní, protože pak je tam potřeba referencovat EF nebo jiný ORM. Proto se na to právě ptám.
To video jsem viděla snad 5x a ještě tak 10x si ho budu muset pustit
Dle mého názoru, když to hodně zevšeobecníme, datová vrstva končí tam,
kde se materializují data. (FirstOrDefault(), ToList()) Jestli před
materializací použiješ Query objekty, repositáře, Automapper a další, je
věcí technologií (návrhové vzory, frameworky), tedy způsob, jakým se k
datům dostáváš. Také platí, že přistupovat k datům může jen tato
vrstva (DAL), business vrstva by neměla k datům přistupovat přímo, ale
používat právě tu DAL (tedy třeba volat nějaký query objekt,
repozitář...)
Pěkný článek je zde:
https://chsakell.com/2015/02/15/asp-net-mvc-solution-architecture-best-practices/
Není to vysloveně špatně, jestliže DAL budeš volat jen ty. Jestli víš jak funguje deferred execution, LINQ provideři a problematika kolem toho, tak možná budeš tušit kde může být zrada.
Nejlehčí příklad je asi to, že jsi v jedné vrstvě, tam zavoláš něco ve smyslu:
return DbContext.Foos; // nějaká kolekce nečeho a vrátíš to jako IQueryable<Foo>
Vrstva, která to volala si to uloží a filtruje si to dál přes LINQ:
var foos = DAL.GetFoos()
.Where(...);
No, ale ta to pošle ještě další a ta až to zavolá
foreach(var foo in BL.GetFoos())
A může se stát, že dostaneš hezké vyjímky, protože tvoje datová vrstva to ve skutečnosti vykonala až když ses ptal na ty data (foreach). A proč to může vyhodit chybu? Protože provider neumí transformovat všechny LINQ/MoreLINQ věci do SQL, protože to třeba ani vůbec nejde.
Takže místo původního plánu:
select * from foo;
->
projekce (namapování na entity)
->
filtrace v paměti
Můžeš ve skutečnosti tohle, ale nemáš tam žádnou garanci, že to bude fungovat.
select * from foo [where ? | join ? | ...]
Btw, prakticky stačí, že nebudeš vracet IQueryable a zavoláš ToList/ToArray/ToHashSet už v DALu a nenecháš tam jen projekci na tvoje DTO.
Hmm, nedostal jsem žádnou notifikaci. Tak já se najím a napíšu
Ahoj, tak tedy proč je vracení IQueryable špatné?
Standardní správné řešení je něco takového
List<Car> GetCarsByTypeAndEngine(string factory, string name, Enum engine)
to proč se vlastně abstrahuje, vyplývá ze solidu, tedy pokud uvnitř
této metody používáš EntityFramework, voláš to takto:
var cars = GetCarsByTypeAndEngine("škoda", "octavia 3",
MotorZeSekacky);
EF není často ideální a proto se ti stane, že chceš vnitřek (přístup k datum - DAL) přepsat na ciste SQL - zde můžeš jen přepsat kod uvnitř té metody a samotný předpis metody nemusíš nijak měnit - OPEN / CLOSED principle.
Nyní si představ že vracíš třeba z repository IQeuryable a máš to takto:
var cars = Repo.Cars.Where(.......); // Tento kod je v BL
Co když dojde ke změně z EF jinam? Kde to přepíšeš, když samotný dotaz nemáš ničim reprezentovaný (samotný dotaz je zde vyjádřený linqem) a co hůře, když je v BLL? musíš to přepsat na 100 místech.
A toto je jen jedna z velkých nevýhod.. Dalěí je třeba leaky abstrakce. Zmiňoval to podemnou už Johny Varga - LINQ nad DB je třeba case in-sensitive, ale jakmile je to ToObjects, tak uz jsi case sensitive. Není to tedy dostatečná abstrakce. ..Už vůbec nezmiňuji třeba LAZY LOADING..
Chybí tam tedy jakási vrstva abstrakce.
Jinak ještě jedna zajímavá věc.. Většina "profíků" ti poví, že netřeba psát repository a UOW nad Entity Frameworkem, protože DBSet je generický repository a DbContext je vlastně UOW... Jenže to je zase to, že tam chybí abstrakce.
Další zajímavá věc je to, že když zadáš na stránkách microsoftu "unit of work", tak tam najdeš tu nejhorší možnou imiplementaci, která rve všechny repository jako service locator do UOW.
Důvod, proč mám v tom návrhu Queries, Commands a Repositories v BLL vrstvě je ten, že jsem to viděl jednak na WUG ve videu T. Hercega Zajímavé návrhové vzory a pak také v příkladech na netu.
Jo také jsem to párkrát viděl a je tam hned několik škaredých věcí - s některýma nesouhlasím absolutně a s jednou jsem vedl s Tomášem X hodinový rozhovor Konkrétně ta implementace UOW.
Těch nelogičností v té implementaci, je více.... Pokud sis třbea zkusil ten UOW zaměnit za standardní SQL z EF, nebo něco podobného, hned ti to bylo jasné
Mimochodem, já vraícm tkaé z určitých metod IQueryable, ale tyto metody lze použít pouze na úrovni DALu a nelze vratit IQueryable z DALu do vyssi vrstvy- používám to fluent kompozitní skládání dotazů:
return persons
.WhereName(..)
.OnlyAlive(..)
.SortByIIRC()
.ToList();
Co je MoreLinq? More jako Moře, HejMoreLinq, nebo to neznám?
Hmm, David dává mínuska už z principu Alespoň si vyčerpal doufám denní limit
Nemyslím si, že bys dostal ten mínus "z principu". Zkusil ses zeptat strejdy gůgla co je MoreLINQ?
Koukám, že David Čápka to tu vede fakt solidním totalitním způsobem - takže třeba můj příspěvek ze 14:16 je nekonstruktivní? Davide, až tu nebudeš zcela neoprávněně zasahovat do něčeho, do čeho ti nic není jen proto, že se ti to nelíbí, tak mi dej vědět. Fakt nemám náladu na tydle tvoje božské ex machiny. Víš co je to sociální síť? Do té doby si strč tudle svoji síť klidně za klobouk.
Zdravím tě, ty jedna železná ruko. MB.
Objevil jsem to pár měsíců z5 a jsou to další extension metody, které mají být už dlouho jako součást LINQu. Skoro všude jsem potřeboval MinBy/MaxBy a psát to pořád dokola mě nebavilo, tak jsem googlil a objevil tu super knihovnu
Pak tam je konečně ForEach, Zip, ... Však na to mrkni.
Zobrazeno 20 zpráv z 20.