Asp.net mvc bad practices

33
ASP.NET MVC - BAD PRACTICES Radu Vunvulea vunvulearadu.blogspot.co m

description

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.

Transcript of Asp.net mvc bad practices

Page 1: Asp.net mvc   bad practices

ASP.NET MVC - BAD PRACTICES

Radu Vunvuleavunvulearadu.blogspot.com

Page 2: Asp.net mvc   bad practices

Radu VunvuleaMail: [email protected]

Blog: vunvulearadu.blogspot.com/

Page 3: Asp.net mvc   bad practices

Agenda• ASP.NET MVC Introduction• Why “BAD PRACTICES”• Some bad practices• More bad practices• And more bad practices• Q&A• Bibliography

Page 4: Asp.net mvc   bad practices

MVC - Model View Controller

Model

ViewController

Page 5: Asp.net mvc   bad practices

De ce “BAD PRACTICES”?

Page 6: Asp.net mvc   bad practices

De ce “BAD PRACTICES”?

2 km

Page 7: Asp.net mvc   bad practices

De ce “BAD PRACTICES”?

20 km

Page 8: Asp.net mvc   bad practices

De ce “BAD PRACTICES”?

900 km

Page 9: Asp.net mvc   bad practices

View Model = Domain model

Repository View

Domain Model

Page 10: Asp.net mvc   bad practices

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

Page 11: Asp.net mvc   bad practices

View Model = Domain model

Page 12: Asp.net mvc   bad practices

View-ul contine logica

Page 13: Asp.net mvc   bad practices

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

Page 14: Asp.net mvc   bad practices

Controller si dependintele exterioare

Page 15: Asp.net mvc   bad practices

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

Page 16: Asp.net mvc   bad practices

Controller si dependintele exterioare

Page 17: Asp.net mvc   bad practices

Controller si dependintele exterioare

Page 18: Asp.net mvc   bad practices

Nu folositi “magic words”

Page 19: Asp.net mvc   bad practices

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

Page 20: Asp.net mvc   bad practices

Nu folositi “magic words”

Page 21: Asp.net mvc   bad practices

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)

Page 22: Asp.net mvc   bad practices

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

Page 23: Asp.net mvc   bad practices

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

?

Page 24: Asp.net mvc   bad practices

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

Page 25: Asp.net mvc   bad practices

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

Page 26: Asp.net mvc   bad practices

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

Page 27: Asp.net mvc   bad practices

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

Page 28: Asp.net mvc   bad practices

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

Page 29: Asp.net mvc   bad practices

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()…

Page 30: Asp.net mvc   bad practices

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

Page 31: Asp.net mvc   bad practices

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

Page 32: Asp.net mvc   bad practices

Q&A

Page 33: Asp.net mvc   bad practices

[email protected]

vunvulearadu.blogspot.com/