NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
Avatar
Majkel
Člen
Avatar
Majkel:12.3.2017 18:00

Ahoj, potřeboval bych poradit s architekturou aplikace. Konkrétněji s referencováním. Momentálně to vypadá tak, jak to popisuju níže. Nejsem si zcela jistý, jestli je to správně. Takže tady bych uvítal připomínky. Co mě ale mate více je referencování. Co jsem vyčetl, tak v DAL mají být pouze entity + konfigurace a context. BLL by pak měla obsahovat Repositáře a Query objekty. V tom případě ale potřebuji nareferencovat EntityFramework kromě DAL, také do BLL vrstvy. Je to tak správně?

Díky za pomoc.

AppName.BLL
• Commands
• Queries
• Repositories (Generický repositář, pouze základní CRUD operace)
• Facades
AppName.DAL
• Configs (FluentApi)
• Contexts (Entity framework context)
• Entities
AppName.WEB (ASP.NET MVC projekt)
• Infrastructure (CastleWindsor, další infr. třídy)
AppName.Models
• DTO
• ViewModels
Ostatní modely

 
Odpovědět
12.3.2017 18:00
Avatar
Odpovídá na Majkel
Michal Štěpánek:12.3.2017 18:31

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ěď...

Nahoru Odpovědět
12.3.2017 18:31
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Odpovídá na Majkel
Marian Benčat:12.3.2017 21:56

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.

Nahoru Odpovědět
12.3.2017 21:56
Totalitní admini..
Avatar
Marian Benčat:12.3.2017 22:00

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é ;-)

Nahoru Odpovědět
12.3.2017 22:00
Totalitní admini..
Avatar
Jan Vargovský
Tvůrce
Avatar
 
Nahoru Odpovědět
12.3.2017 22:37
Avatar
Marian Benčat:12.3.2017 22:47

proc?:D kdybych mel blbej den, tak povim jen, ze jsou blbky :D ted se snazim pomoci a ocekavam dotaz, proc je vracet iqueryable spatne a proc by to cele nemelo byt v BL

Editováno 12.3.2017 22:48
Nahoru Odpovědět
12.3.2017 22:47
Totalitní admini..
Avatar
Odpovídá na Majkel
Marian Benčat:12.3.2017 22:55

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.

Nahoru Odpovědět
12.3.2017 22:55
Totalitní admini..
Avatar
Jan Vargovský
Tvůrce
Avatar
Odpovídá na Marian Benčat
Jan Vargovský:13.3.2017 7:19

No ode mne se ho nedočkáš :D ono to ani není moc k tématu tbh :)

 
Nahoru Odpovědět
13.3.2017 7:19
Avatar
Majkel
Člen
Avatar
Majkel:13.3.2017 16:42

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.

 
Nahoru Odpovědět
13.3.2017 16:42
Avatar
Odpovídá na Majkel
Nikola Sterziková (PaNika):13.3.2017 18:03

To video jsem viděla snad 5x a ještě tak 10x si ho budu muset pustit :-D
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/
 
Nahoru Odpovědět
13.3.2017 18:03
Avatar
Jan Vargovský
Tvůrce
Avatar
Odpovídá na Majkel
Jan Vargovský:13.3.2017 18:05

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/ToArra­y/ToHashSet už v DALu a nenecháš tam jen projekci na tvoje DTO.

 
Nahoru Odpovědět
13.3.2017 18:05
Avatar
Marian Benčat:14.3.2017 11:52

Hmm, nedostal jsem žádnou notifikaci. Tak já se najím a napíšu :D

Nahoru Odpovědět
14.3.2017 11:52
Totalitní admini..
Avatar
Odpovídá na Majkel
Marian Benčat:14.3.2017 14:16

Ahoj, tak tedy proč je vracení IQueryable špatné?

  • Je potřeba si uvědomit k čemu je DAL, k čemu jsou repository a k čem jsou Query objecty - nejedná se o nic jiného, než o abstrakci přístup k datum. tedy jakási reprezentace dotazu.

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 = GetCarsByType­AndEngine("ško­da", "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é ;-)

Nahoru Odpovědět
14.3.2017 14:16
Totalitní admini..
Avatar
Marian Benčat:14.3.2017 14:19

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();
Editováno 14.3.2017 14:20
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
14.3.2017 14:19
Totalitní admini..
Avatar
Odpovídá na Jan Vargovský
Marian Benčat:14.3.2017 14:21

Co je MoreLinq? More jako Moře, HejMoreLinq, nebo to neznám? :D

Editováno 14.3.2017 14:21
Nahoru Odpovědět
14.3.2017 14:21
Totalitní admini..
Avatar
Marian Benčat:14.3.2017 16:39

Hmm, David dává mínuska už z principu :-) Alespoň si vyčerpal doufám denní limit ;-)

Nahoru Odpovědět
14.3.2017 16:39
Totalitní admini..
Avatar
Odpovídá na Marian Benčat
Michal Štěpánek:14.3.2017 16:56

Nemyslím si, že bys dostal ten mínus "z principu". Zkusil ses zeptat strejdy gůgla co je MoreLINQ?

Nahoru Odpovědět
14.3.2017 16:56
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Neaktivní uživatel:14.3.2017 17:47

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.

Nahoru Odpovědět
14.3.2017 17:47
Neaktivní uživatelský účet
Avatar
Jan Vargovský
Tvůrce
Avatar
Odpovídá na Marian Benčat
Jan Vargovský:14.3.2017 18:14

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.

Editováno 14.3.2017 18:16
 
Nahoru Odpovědět
14.3.2017 18:14
Avatar
Majkel
Člen
Avatar
Majkel:5.4.2017 17:35

Tak jsem si vzal k srdci zdejší rady, včetně nevracení IQueryable. Díky za diskusi a tipy.

 
Nahoru Odpovědět
5.4.2017 17:35
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 20 zpráv z 20.