Asp.net mvc bad practices

  • View
    1.111

  • Download
    0

  • Category

    Business

Preview:

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.

Citation preview

ASP.NET MVC - BAD PRACTICES

Radu Vunvuleavunvulearadu.blogspot.com

Radu VunvuleaMail: vunvulear@gmail.com

Blog: vunvulearadu.blogspot.com/

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

MVC - Model View Controller

Model

ViewController

De ce “BAD PRACTICES”?

De ce “BAD PRACTICES”?

2 km

De ce “BAD PRACTICES”?

20 km

De ce “BAD PRACTICES”?

900 km

View Model = Domain model

Repository View

Domain Model

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

View Model = Domain model

View-ul contine logica

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

Controller si dependintele exterioare

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

Controller si dependintele exterioare

Controller si dependintele exterioare

Nu folositi “magic words”

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

Nu folositi “magic words”

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)

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

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

?

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

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

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

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

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

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

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

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

Q&A

vunvulear@gmail.com

vunvulearadu.blogspot.com/