An overview over the most common bad practices in ASP.NET MVC 3. In this session we will discuss about some mistakes that are made in an ASP.NET MVC 3 applications and what we can do to avoid them.
9. View Model = Domain model
Repository View
Domain Model
10. View Model = Domain model
• In view o sa ajunga mai multe date decat este necesar
• Entitatea o sa fie poluata cu diferite atribute ce tin de UI
• Nu exista o separare clara a fiecarui layer
• Modelul este un DTO (Data Transfer Object) si ar putea sa fie
compus doar din string-uri
• Un convertor se poate folosi pentru a obtine un model dintr-o
entitate (intr-un sens, in doua sensuri)
• Un framework pentru maparea entitatilor (AutoMapper)
• Codul care face conversia nu se duplica
• Controller-ul nu creste ca si complexitate din cauza conversiei
13. View-ul contine logica
• In view modelul este procesat
• Modelul nu contine date in stare finala
• View-ul ar trebui doar sa afiseze modelul
• Logica de procesare nu are ce cauta in view
• Din view nu se apeleaza clase exterioare
• Un view poate sa contina IF si FOR (FOREACH)
• SWITCH – chiar avem nevoie de el?
• Daca populam modelul corect, IF-ul poate sa fie inlocuit cu un
HtmlHelper
15. Controller si dependintele exterioare
• Controller-ul nu ar trebui sa acceseze direct HttpContext, baza de
date sau orice alta resursa
• Setarile din web.config nu trebuie accesate direct
• Este mai greu de testat
• Nu este flexibil
• Orice schimbare poate sa genereze foarte multe modificari
• Se poate construi un wrapper peste aceste dependinte
• Wrapperul poate sa grupeze datele din punct de vedere logic si nu in
functie de sursa lor
• ActionFilter care sa ne ofere aceste date
19. Nu folositi “magic words”
• Cand se acceseaza sesiunea, ViewData, ViewBag, etc
• Pot sa apara foarte usor greseli de scriere (misspelling)
• Duplicarea informatiei – aceiasi informatie in mai multe locuri
• Aceiasi conversie de date se face in mai multe locuri
• Nu o sa stiti cauza pentru care view-ul crapa (misspelling sau datele
nu au fost puse unde trebuie)
• Wrapper
• Extension methods
• Datele de care avem nevoie in view se pot trimite prin model si nu
prin alte mecanisme
21. Nu hardcodati RouteUrl-urile
• Evitati sa folosti Html.ActionLink in view
• Evitati sa folosti RedirectToAction in controller
• Puteti crea extension methods pentru fiecare url
• Le puteti refolosi in mai multe locatii (atat in view cat si in controller)
• Creati extension methods si pentru locatiile la resurse (image
path, JavaScript path, CSS files path)
22. Repopulare date comune in Model
• 2 sau mai multe modele contin aceleasi date
• Creati o structura de clase
(BaseUserModel, CustomerUserModel, AdminUserModel)
• Populati modelul de baza dintr-un singur loc
23. Repopulare date comune in Model
• 2 sau mai multe modele contin aceleasi date
• Creati o structura de clase (BaseUserModel, CustomerUserModel,
AdminUserModel)
• Populati modelul de baza dintr-un singur loc
?
24. Agregare date pentru o actiune
• Daca avem nevoie de acelasi ActionFilter in mai multe actiuni, atunci
incercati sa le puneti intr-un sigur loc (intr-un BaseController)
• Folositi ActionFilter pentru a transforma datele care vin din diferite
locatii in parametri pentru actiune
25. Fat Controller
• Apeleaza direct baza de date
• Proceseaza informatia
• Logica din el este foarte complexa – toata partea fun este in controller
• Are foarte multe actiuni
• Multe entitati sunt cuplate prin intermediul controller-ului
• Greu de inteles, modificat si testat
• Controller-ul nu trebuie sa fie strans legat de domeniu
• Nu el trebuie sa fie dirijorul aplicatiei noastre
• Un controller per functionalitate si nu per entitate
26. Fat Controller
• Un controller per functionalitate si nu per entitate
• Fiecare functionalitate care este oferita de catre aplicatia noastra
poate sa fie reprezentata de catre un controller
• Un controller per use case – nu este mereu posibil
27. Actiunile apelate des nu sunt cache-uite
• Daca avem actiuni care sunt apelate des, iar continutul ramane la
fel, atunci putem sa folosim OutputCache
• Nu poluati controller-ul cu configurarea cache-ului
• Cache-ul trebuie configurat din web.config si nu din controller
28. Framework-ul de DI este apelat direct
• In anumite factory-uri (ControllerFactory) se apeleaza direct clase care
tin de framework-ul de DI
• Diferite proiecte folosesc diferite DI
• Creati un wrapper peste acestea, care sa abstractizeze API-ul
• Folositi Common Service Locator
• Este o abstractizare peste mecanismul de DI, care iti permite sa
folosesti acelasi API indiferent de ce framework de DI folosesti
29. HtmlHelper - overused
• Nu creati un extension method la un HtmlHelper daca nu este folosit
cel putin in doua locuri
• Incercati sa grupati aceste metode sub un nod comun daca se poate
• O sa fie mai usor de folosit si de inteles
HtmlHelper
.Table()
.BoxList()
.Pivot
.Product() – returneaza ProductHtmlHelper
.FormatPrice()
.Stock()
…
…
30. JavaScript in View
• Oricat de scurt este JavaScript-ul nu il puneti in view
• JavaScript-ul o sa polueze view-ul si o sa il faca greu de inteles
• Nu faceti apeluri AJAX din View
• Nu hardcodati adresa url pentru AJAX in JS – use UrlHelper
• Ce se intampla daca o actiune se redenumeste ?
• Ce se intampla daca locatia unei resurse se schimba?
• Trebuie facute in mai multe locuri modificari
31. View-uri foarte lungi
• Cat de normal este sa ai un view de 100 de randuri, iar codul sa se
repete?
• Cat de normal este ca intr-un FOR dintr-un view sa se afiseze contintul
unui “sub-model” direct?
• Pentru aceste cazuri se poate folosi Partial View
• Nu conteaza daca acesta are doar 2 randuri sau 10
• Reutilizarea codului creste
• Devine mai clar
• Mai usor de citit si testat