15 noiembrie 2014

(P) Marcaje.dev - Marcaje open source și Manager de fragmente de cod pentru dezvoltatori & Co. Consultați ghidurile noastre Cum să vă ajute să începeți. Repoare marcaje publice pe Github - Star

metode extensie

Această postare de blog este dedicată colegei mele Seminda, care a experimentat cum să creeze aplicații web simple și puternice. Mulțumesc că mi-ai arătat ideile tale și ai discutat cu mine despre îmbunătățiri, Seminda.

Am găsit că multe aplicații C # au cod mult inutil. Acest lucru este valabil mai ales, deoarece ponderea logicii de afaceri a multor aplicații se schimbă de la backend la cod JavaScript în paginile web. Când sarcina aplicației dvs. este de a furniza date către un front-end, este important să le mențineți subțiri.

În acest articol, mi-am propus să simplific un controler API MVC 4 standard generalizând funcționalitatea, centralizând gestionarea excepțiilor și adăugând metode de extensie la setul de baze de date care este folosit pentru preluarea datelor mele.

Dacă generați un controler API bazat pe o entitate existentă și eliminați o parte din zgomot, codul dvs. ar putea arăta astfel:

Acest cod este o versiune simplificată a ceea ce vă va oferi expertul API 4 Controller. Include o metodă GetPerson care returnează o persoană prin Id, PostPerson care salvează o persoană nouă, GetPeople care returnează toate persoanele din baza de date, GetAdminsInCity, care filtrează oamenii pe oraș și tip și DeletePerson care găsește persoana cu ID-ul specificat și îl șterge.

Am înlocuit DbContext și IDbSet cu interfețe în loc de subclasa concretă a DbContext facilitează crearea de teste care utilizează o dublă pentru baza de date, de exemplu MockDbSet.

Generați controlerul

Acest lucru este ușor și sigur, atâta timp cât lucrurile sunt simple. Ca sfat general, redenumiți-vă metodele în „Obțineți”, „Postați” și „Index”, mai degrabă decât „GetPerson”, „PostPerson” și „GetPeople”. Acest lucru va face posibilă generalizarea controlerului astfel:

EntityController generic poate fi utilizat pentru orice clasă care este gestionată cu EntityFramework.

Manevrarea excepțiilor

Voi îndrăzni să fac o generalizare îndrăzneață: Majoritatea erorilor care rămân în software-ul de producție sunt tratate cu erori. Prin urmare, am un ghid foarte simplu: nu există blocuri de prindere care să nu retragă o altă excepție.

Tratarea efectivă a excepțiilor ar trebui să fie centralizată. Acest lucru face ca codul să fie mai ușor de citit și asigură că excepțiile sunt tratate în mod consecvent. În MVC 4, locul pentru a face acest lucru este cu un ExceptionFilterAttribute.

Astfel, putem simplifica EntityController:

HandleApplicationException arată astfel:

Acest cod de cod adaugă, desigur, tratarea specială a altor tipuri de excepții, jurnalizare etc.

Dbset ca depozit

Dar o singură piesă rămâne în PersonController: utilizarea destul de complexă a LINQ pentru a face o interogare specializată. Aici mulți dezvoltatori ar introduce un depozit cu un „FindAdminsByCity” specializat și poate chiar un strat de servicii separat cu o metodă pentru „FindSummaryOfAdminsByCity”.

Dacă începeți pe acea cale, multe echipe vor alege să introducă aceleași straturi (serviciu și depozit) chiar și atunci când aceste straturi nu fac nimic și creează o mulțime de volume în aplicațiile lor. Din experiența mea personală, acest lucru merită să luptăm! Straturile inutile sunt cauza unei cantități uriașe de cod inutil în aplicațiile moderne.

În schimb, puteți utiliza metode de extensie C #:

Metoda controlerului rezultată devine frumoasă și încapsulată:

Este destul de minim și simplu!

Am arătat trei trucuri pentru a reduce complexitatea controlerelor dvs.: În primul rând, părțile controlerelor dvs. pot fi generalizate, mai ales dacă evitați numele entității în numele metodelor de acțiune; în al doilea rând, gestionarea excepțiilor poate fi centralizată, eliminând zgomotul din fluxul principal de aplicații și asigurând coerența; în cele din urmă, folosind metode de extensie pe IQueryable

oferă domeniului meu DbSet metode specifice fără a fi nevoie să implementez straturi suplimentare în arhitectură.

Mi-ar plăcea să aud dacă utilizați această abordare sau dacă ați încercat ceva asemănător, dar ați găsit că lipsește.