FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința...

66
UNIVERSITATEA „ALEXANDRU IOAN CUZA” IAŞI FACULTATEA DE INFORMATICĂ LUCRARE DE LICENŢĂ FoodApp propusă de Largu Dragoș Constantin Sesiunea: iulie 2016 Coordonator ştiinţific Asist. Dr. Vasile Alaiba

Transcript of FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința...

Page 1: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

UNIVERSITATEA „ALEXANDRU IOAN CUZA” IAŞI

FACULTATEA DE INFORMATICĂ

LUCRARE DE LICENŢĂ

FoodApp

propusă de

Largu Dragoș Constantin

Sesiunea: iulie 2016

Coordonator ştiinţific

Asist. Dr. Vasile Alaiba

Page 2: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

UNIVERSITATEA „ALEXANDRU IOAN CUZA” IAŞI

FACULTATEA DE INFORMATICĂ

FoodApp

Largu Dragoș Constantin

Sesiunea: iulie 2016

Coordonator ştiinţific

Asist. Dr. Vasile Alaiba

Page 3: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

DECLARAŢIE PRIVIND ORIGINALITATE ŞI RESPECTAREA

DREPTURILOR DE AUTOR

Prin prezenta declar că Lucrarea de licenţă cu titlul „FoodApp” este scrisă de mine și nu a

mai fost prezentată niciodată la o altă facultate sau instituție de învățământ superior din țară sau

străinătate. De asemenea, declar că toate sursele utilizate, inclusiv cele preluate de pe Internet, sunt

indicate în lucrare, cu respectarea regulilor de evitare a plagiatului:

- toate fragmentele de text reproduse exact, chiar și în traducere proprie din altă limbă, sunt scrise

între ghilimele și dețin referința precisă a sursei;

- reformularea în cuvinte proprii a textelor scrise de către alți autori deține referința precisă;

- codul sursă, imaginile etc. preluate din proiecte open-source sau alte surse sunt utilizate cu

respectarea drepturilor de autor și dețin referințe precise;

- rezumarea ideilor altor autori precizează referința precisă la textul original.

Iași,

Absolvent Largu Dragoș Constantin

___________________________

Page 4: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

DECLARAŢIE DE CONSIMŢĂMÂNT

Prin prezenta declar că sunt de acord ca Lucrarea de licență cu titlul „FoodApp”, codul sursă

al programelor şi celelalte conţinuturi (grafice, multimedia, date de test etc.) care însoţesc această

lucrare să fie utilizate în încheiată cadrul Facultăţii de Informatică.

De asemenea, sunt de acord ca Facultatea de Informatică de la Universitatea „Alexandru

Ioan Cuza” Iași să utilizeze, modifice, reproducă şi să distribuie în scopuri necomerciale

programele-calculator, format executabil şi sursă, realizate de mine în cadrul prezentei lucrări de

licenţă.

Iași,

Absolvent Largu Dragoș Constantin

___________________________

Page 5: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

5

Introducere și motivație

Prin lucrarea de față propun o abordare multi-nivel (multi-tier) pentru rezolvarea unei

probleme foarte des întâlnite în viața de zi cu zi: ce feluri de mâncare ar putea fi gătite folosind

ingredientele care se găsesc în frigider.

„Ingrediente” se referă la orice componentă generică a unui fel de mâncare, nu neapărat o

componentă unitară (spre exemplu pentru anumite feluri de mâncare putem considera ciocolata ca

fiind un ingredient, deși tehnic vorbind, ciocolata este la rândul ei compusă din alte ingrediente).

Atât în cadrul lucrării, cât și în cadrul ecosistemului aplicației însoțitoare, ne referim la aceste

componente generice drept Ingrediente.

„Felurile de mâncare” se referă la structuri complexe formate din Ingrediente, cantități și

instrucțiuni de folosire (trebuie să existe măcar două ingrediente asociate). Asemănător cu

Ingredientele, ne referim la aceste feluri de mâncare drept Rețete.

Motivația din spatele creării acestei soluții se întinde pe doua arii principale:

Aria non-tehnică

o Pasiunea mea personală pentru gătit

o Dorința de avea o modalitate de sugestie a rețetelor posibile pe baza

ingredientelor disponibile, sub formă unei aplicații pe telefon

o Dorința de a putea administra diverse aspecte ale aplicației folosind o soluție

server

Aria tehnică

o Pasiunea mea personală pentru programarea în .Net pe Web și Mobil

o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind

cele mai noi tehnologii

o Dorința de a demonstra cum se poate scrie cod curat folosind propriul meu

Coding Style

Trebuie menționat că în mod surprinzător, pe piața aplicațiilor WindowsPhone nu există

încă nici o aplicație care să îndeplinească măcar parțial funcționalitatea pe care eu am creat-o, deși

în domeniul public există o serie de API-uri (unele gratuite, altele nu) care oferă accesul la baze de

Page 6: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

6

date ce conțin Ingrediente și Rețete, cu acces bazat pe request-uri REST. Am ales WindowsPhone

pentru că eu personal sunt utilizator WindowsPhone de aproximativ 4 ani.

Nu am dorit să depind de API-uri externe (motivația fiind că nu am nici o certitudine privind

viitorul lor), așa că am creat propria mea versiune de API.

Practic, aplicația se împarte în trei componente mari, la care se mai adaugă o serie de

componente portabile (detaliate pe parcursul lucrării):

Serverul (aplicație de tip .Net Web)

o Oferă pagini web cu interfețe grafice prietenoase în scopuri de Debug (folosind

ASP.Net MVC 5)

o Oferă acces la request-uri de tip REST (folosind ASP.Net WebApi 2)

o Este găzduită folosind Windows Azure1

Interfață de Operațiuni (aplicație de tip PCL2)

o Acționează ca şi intermediar între server şi client (pentru a evita comunicația

directă între server şi client)

o Apelează toate operațiunile de tip REST3 disponibile pe server

o Oferă o interfață pentru pentru consumarea metodelor REST de pe server de

către client

Clientul (aplicație de tip .Net WindowsPhone4)

o Rulează pe Windows Phone 8.1 (cu posibilitate de deployment şi pe Windows

Phone 10 şi Windows 8.1/Windows 10)

o Oferă utilizatorilor posibilitatea de folosi diverse ingrediente pentru a caută

diverse rețete disponibile

Prin interacțiunea celor trei componente, se creează ecosistemul multi-nivel ce constituie

aplicația mea, numită generic FoodApp.

1 Adresa de găzduire este http://foodappwebapi.azurewebsites.net/ 2 PCL – Portable Class Library – librărie .Net construită folosind un sub-set al framework-ului, ce poate fi folosită in

orice tip de aplicație .Net 3 REST – Representational State Transfer – protocol de comunicare Client – Server folosind protocolul HTTP 4 .Net WindowsPhone – subset al framework-ului .Net folosit pentru construirea aplicațiilor pentru platforma mobilă

Windows Phone

Page 7: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

7

Contribuții

Tematica lucrării a fost propusă de către mine, bazându-se pe ideea de unificare a

elementelor server - proxy5 - client pentru a creea un ecosistem unitar, propunere transmisă

domnului profesor Vasile Alaiba (coordonatorul meu) - mai ales din pricina experienței dumnealui

în domeniul dezvoltării profesionale al aplicațiilor Mobile (iOs / Android / WindowsPhone).

Elementele teoretice şi practice folosite în dezvoltarea lucrării provin în proporție

majoritară din experiența mea profesională pe ASP.Net şi WindowsPhone, completându-se cu

elemente de Ingineria Programării, Programare Orientată Obiect şi Programare .Net dobândite în

facultate.

Colaborarea student - coordonator s-a concentrat în mare parte pe observație şi îndrumare

din partea domnului profesor, prin intermediul discuțiilor şi a prezentărilor periodice în grup, şi

prin intermediul transmiterii periodice a statusului.

Un mare beneficiu l-a reprezentat conectarea folosind platforme de socializare (în acest caz

Facebook), unde a fost creat un grup privat de discuții pentru coordonarea studenților înscriși la

licenţă şi dizertație sub îndrumarea domnului profesor Alaiba.

Optând pentru folosirea rețelelor de socializare alături de e-mail şi întâlniri periodice s-a

obținut transparență în comunicare şi în observarea progresului contribuind de asemenea la

eficientizarea colaborării prin dărmarea efectivă a multora din barierele mentale care se întâlnesc

deseori în astfel de situații.

De asemenea, alte două contribuții majore în asigurarea transparenței pe parcursul

procesului de dezvoltare software le reprezintă:

folosirea unui sistem de subversionare a codului (în cazul de fată - soluția celor de la

Microsoft numită Team Foundation Server)

o prin subversionare se poate urmări istoricul codului din fiecare fișier în parte,

observând evoluția în timp

o se elimina practic orice șansă de fraudă, prin caracterul evolutiv foarte ușor

demonstrabil

5 Proxy – denumirea tehnică pentru o aplicație cu rol de intermediar (in acest caz aplicația intermediară dintre server

și client)

Page 8: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

8

folosirea unui sistem de gestionare pentru User Stories (în cazul de fată Backlog-ul

oferit de TFS)

o fiecare comitere a codului se leagă de un anumit User Story sau de un anumit

Task subordonat unui User Story, astfel încât, din nou, se poate urmări foarte

ușor evoluția codului în timp

Toate elementele enumerate mai sus au contribuit cu succes la cererea acestei lucrări, şi a

aplicației atașate - vom intră în detalii legate în mod special de folosirea TFS-ului şi a conceptelor

de Backlog, User Story şi Task în cele ce urmează.

Page 9: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

9

Cuprins

Introducere și motivație .................................................................................................................................................. 5

Contribuții ...................................................................................................................................................................... 7

Capitolul 1 - Platforme de management ....................................................................................................................... 10

1.1 Team Foundation Server .................................................................................................................................... 10

1.1.1 Backlog-ul în TFS ...................................................................................................................................... 11

1.1.2 Build-uri XAML și vNext .......................................................................................................................... 13

1.1.3 Continuous Integration ............................................................................................................................... 15

1.2 Windows Azure ................................................................................................................................................. 16

1.2.1 Serviciul de Web Hosting .......................................................................................................................... 17

1.2.2 Serverul și baza de date SQL ..................................................................................................................... 18

1.3 NuGet ................................................................................................................................................................ 19

1.4 LucidChart ......................................................................................................................................................... 20

Capitolul 2 – Pattern-uri arhitecturale .......................................................................................................................... 21

2.1 Design By Contract............................................................................................................................................ 21

2.2 MVC .................................................................................................................................................................. 26

2.3 WebApi .............................................................................................................................................................. 27

2.4 MVVM .............................................................................................................................................................. 28

Capitolul 3 - Structura și conținutul repository-ului ..................................................................................................... 30

Capitolul 4 - Proiectele create ...................................................................................................................................... 35

4.1 DIContainer ....................................................................................................................................................... 36

4.1.1 Detalii arhitecturale .................................................................................................................................... 36

4.1.2 Unit Testing folosind Mock-uri ................................................................................................................. 38

4.1.3 Portabilitatea soluției ................................................................................................................................. 39

4.2 FoodAppWebApi ............................................................................................................................................... 40

4.2.1 Detalii arhitecturale .................................................................................................................................... 41

4.2.2 Baza de date ............................................................................................................................................... 49

4.2.3 Portabilitatea Modelelor ............................................................................................................................. 51

4.3 FoodAppOperationApi ...................................................................................................................................... 52

4.3.1 Design și motivație .................................................................................................................................... 52

4.3.2 Portabilitatea soluției ................................................................................................................................. 54

4.4 FoodAppPhoneApp ........................................................................................................................................... 54

4.4.1 Detalii arhitecturale .................................................................................................................................... 54

4.4.2 Mockup-urile ecranelor .............................................................................................................................. 59

Concluzii și provocări .................................................................................................................................................. 62

Bibliografie ................................................................................................................................................................... 66

Page 10: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

10

Capitolul 1 - Platforme de management

Pe întreg parcursul dezvoltării aplicației și a lucrării scrise am folosit o serie de platforme

specifice pentru managementul de proiecte, pentru a eficientiza subversionarea codului,

colaborarea în scrierea documentației și crearea de diagrame. În continuare voi intra în detalii

relativ la contribuția fiecărei platforme în parte.

1.1 Team Foundation Server

Team Foundation Server este o platformă creată de Microsoft, complexa și capabila să facă

fata la un număr foarte mare de potențiale operațiuni.

TFS este disponibil atât online (rulând pe serverele externe ale Microsoft), cât și local

(putând fi instalat și rulat pe un server local). Funcționalitatea este vânduta pe bază de subscripții

lunare (prețul depinde de tipul de subscripție, fiecare subscripție oferind acces la funcționalități din

ce în ce mai complexe). Eu am optat pentru o subscripție online gratuită.

Din multitudinea de funcționalități oferite de TFS, cele mai relevante pentru elaborarea

acestei lucrări sunt următoarele:

Accesul la un backlog (detalii în subcapitolul 1.1.1)

o Include și managementul iterațiilor folosind template-uri de Agile și

Kanban (managementul sprint-urilor în general)

Managementul Build-urilor (detalii în subcapitolul 1.1.2 și 1.1.3)

Gated Checkins și Continuous Integration (detalii în subcapitolul 1.1.4)

Posibilitatea de a creea o echipă și a manipula drepturile de acces ale membrilor

Subversionarea codului

o Subversionarea în general asigura stocarea codului într-o maniera sigura,

cu posibilitatea de a urmări evoluția în timp, prin consultarea istoricului

fiecărui checkin

o Fiecare checkin se poate lega de un Task sau de un Backlog Item, astfel

încât se poate urmări ușor conexiunea dintre bucăți de cod aliatoare și

itemi funcționali

Page 11: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

11

1.1.1 Backlog-ul în TFS

Backlog-ul este un concept des întâlnit în dezvoltarea software, și se refera practic la o

colecție mare de itemi de lucru numiți Product Backlog Items, pe scurt PBI.

Un PBI reprezintă un requirement creat de către o persoana dedicată, care poate purta

denumiri diferite în funcție de metodologia de dezvoltare folosită (spre exemplu în metodologia

Agile, responsabilul pentru Backlog este numit Product Owner). PBI-urile pot fi funcționale (itemi

cu impact tangibil asupra funcționalității, reflectate de obicei prin schimbări de interfața grafica

sau adăugare/editare/ștergere a anumitor funcționalități), sau non-funcționale (itemi ale căror efecte

nu sunt observabile pe interfețele expuse utilizatorilor, schimbările fiind în interiorul codului –

exemplu reautorizări, update-uri de librării, optimizări de cod, etc).

În cazul meu, proprietarul Backlogului am fost eu însumi (tema fiind propusa de către mine,

am avut libertatea să îmi construiesc singur requirementurile).

În general, metodologiile de dezvoltare software folosite în mediul profesional recomandă

ca un PBI să îndeplinească o serie de criterii:

Sa fie cât mai concise, și să nu lase loc de interpretări

Sa fie împărțite în Task-uri (subcomponente care detaliază pașii spre obținerea finală a

funcționalității descrise în PBI)

Sa fie formulate într-un anumit fel

o Spre exemplu, o maniera des întâlnita este formularea de tip „Ca și rol X doresc

funcționalitatea Y din cauza motivului Z” – exemplu „Ca și utilizator doresc

să îmi pot seta o parola pentru a-mi securiza contul și a-mi proteja datele”

Eu m-am rezumat doar la cererea de PBI-uri concise, însoțite de Task-uri, fără a folosi o

formulare specifica.

Fiecare PBI are anumite stări în care se poate afla la un moment dat (stări care pot fi definite

în TFS), în cazul meu am optat pentru:

To Do – reprezintă starea inițiala a unui PBI, imediat după ce a fost scris, urmând ca el

să fie executat în viitor

În Progress – reprezintă starea intermediara a unui PBI, însemnând că am demarat

lucrul la el

Done – reprezintă starea finală, în care dezvoltarea s-a terminat și itemul a fost testat

Page 12: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

12

În mediul profesional, se include de regula o stare în plus, numita În Test, situata între În

Progress și Done, de care responsabilă este echipa de testare și care semnalează că dezvoltarea

este încheiată și testarea poate începe.

Din punct de vedere vizual, Backlog-ul poate fi folosit asemenea unei liste de PBI-uri, sau

se poate folosi așa-numitul Board, ce oferă posibilitatea de a muta itemi în alte categorii, de a creea

itemi noi, și de a vizualiza rapid și ușor situația curenta a sprintului.

Figura 1- TFS Backlog Board cu PBI-uri si Task-uri vizibile

Page 13: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

13

1.1.2 Build-uri XAML și vNext

TFS oferă posibilitatea de a creea ceea ce se numește un Build, însemnând un pachet ce

conține codul compilat (fie Debug, fie Release), construit de așa natura încât acesta poate fi rulat

oriunde.

Pentru a creea un Build este necesar un Build Definition (se de pași care trebuie urmați

pentru obține rezultatul dorit), care poate fi de doua feluri:

Build vNext (Modelul nou, orientat spre servici web)

o Editabil doar din interfața web a TFS-ului

o Suporta o multitudine de interacțiuni cu servicii externe (spre exemplu se poate

adaugă un pas pentru reconstruirea dependințelor de NuGet la fiecare rulare)

o La fel ca și în cazul Build-urilor XAML, pașii sunt iterativi și potențial

eliminatorii

Build XAML (Modelul clasic oferit de TFS)

o Editabil direct din Visual Studio

o Pașii (cupluri Cheie-Valoare) sunt cereați în formă unui document XML, într-o

interfața XAML

o Execuția pașilor se face în mod iterativ, fiecare pas fiind potențial eliminatoriu

(dacă un pas eșuează, eșuează întregul proces)

o Exista suport limitat pentru interacțiuni cu servicii externe (spre exemplu se

poate face deployment automat pe Windows Azure)

Figura 2 - Build Definition pentru vNext Build

Page 14: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

14

Ambele variante de Build suportă rularea Unit Testelor ca și pas individual, însemnând că

se poate creea o regula care necesită ca Unit Testele să se ruleze cu succes, în caz contrar, Build-

ul poate fi refuzat.

Ca și detaliu de implementare internă, se poate menționa că TFS-ul creează Build-uri

folosind mașini virtuale, pe care rulează un proces Winows specific numit Build Agent. Acest

Agent primește codul compilat, se ocupa de întregul proces (execuția pașilor), și la final returnează

pachetul, în caz de succes.

Figura 2- Build Definition pentru XAML Build

Procesul intern este încapsulat într-o maniera în care utilizatorul TFS nu observa existenta

mașinilor virtuale în cazul operațiunilor de bază. Rularea TFS-ului pe un server local însă, eventual

cu reguli costumate, necesită o adânca înțelegere a proceselor încapsulate, pentru a putea manipula

sistemul.

În cazul meu, așa cum se poate observa și în imaginile de mai sus, am folosit ambele tipuri

de Build, rezumându-mă la setările standard, fără să manipulez procesul în sine.

Page 15: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

15

1.1.3 Continuous Integration

Motivația principala pentru folosirea sistemului de Build oferit de către TFS este

posibilitatea de integrare continua a codului, așa numita Continuous Integration.

Ideea pe care se bazează procesul este aceea că orice proiect trebuie să fie în orice moment

perfect rulabil și funcțional, în versiunile existente pe sistemele de subversionare. În mod obișnuit,

în mediul profesional, există minim trei medii de stocare pentru codul unui proiect:

Mediul de Testare (mediul pe care se executa testarea de către echipele de Quality

Assurance)

Mediul de Staging (un mediu perfect identic cu mediul clienților, pe care se executa

testare în condiții realistice)

Mediul Clienților (mediul folosit de clienți, finalitatea produsului software)

În cazul meu, am un singur mediu, care tine loc de toate cele trei medii clasice, însemnând

că atunci când fac checkin la cod, nu mai trec prin etapele de transfer între medii, ci merg direct pe

un singur mediu.

Aceste medii de fapt reprezintă servere fizice (mașini dedicate sau mașini virtuale) pe care

este stocat câte un Build al aplicației. Pe măsura de se finalizează testarea pe un mediu, Build-ul

este transferat pe următorul mediu, în mod incremental.

Transferarea Build-urilor pe medii se poate face prin procesul automatizat de Continuous

Integration, în felul următor:

La fiecare checkin al codului, se rulează Build Definition-ul și se creează un Build

Acel Build trebuie să respecte regulile din definiție (spre exemplu trebuie să treacă cu

succes toate Unit Testele)

În cazul în care una din reguli eșuează, Build-ul nu este acceptat

Build-ul este copiat (deployment) pe mediul de lucru (spre exemplu pe mediul de

testare)

Acest proces suprascrie adaugă Build-ul nou peste Build-ul vechi, creând continuitate, prin

existenta posibilității ca oricând să se facă un pas în spate spre un Build precedent.

Procesul prin care se decide dacă un Build este acceptat sau nu se numește, în cazul TFS-

ului, Gated Checkin (checkin păzit prin porți de acces, administratorii având posibilitatea de a seta

funcționalități specifice fiecărei porți).

Page 16: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

16

În cazul meu, am folosit sistemul de Integrare Continua prin Gated Checkins pentru

siguranța pe care o oferă aceasta abordare, și pentru ușurința ei de folosire (cum se poate observa

în poza de mai jos).

Facilitatea de creare automată a Build-ului este un argument pro foarte puternic (în opoziție

cu stilul clasic de copiere directa a codului și publicare manuala a schimbărilor).

1.2 Windows Azure

Windows Azure este platforma Cloud a celor de la Microsoft, folosită pentru o multitudine

de operațiuni, de la găzduire site-uri web pana la găzduire mașini virtual și server fizice. Se poate

interacționa cu Azure atât prin intermediul site-ului lor (via un Portal de Management – versiune

veche și versiune nouă, cu diferențe sesizabile din punct de vedere a posibilităților de utilizare,

extrem de ușor de costumata din punct de vedere vizual), cât și prin intermediul unui API-ului

programatic (disponibil mai ales în PowerShell).

Accesul este oferit pe baza unui cont Microsoft, iar majoritatea serviciilor oferite au doar

variante pentru uz comercial, cu plata (preturile fiind ori standard, ori negociabile pentru pachete

Figura 4 - Continuous Integration și Gated Checkins în TFS

Page 17: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

17

costumate – exemplu cererea de server SQL), însă există și câteva servicii gratuite, strict pentru uz

personal sau educațional (exemplu găzduirea de site-uri web). Fiecare serviciu oferit este disponibil

pe baza unei subscripții lunare (taxata în funcție de prețul ales pentru fiecare serviciu), iar aceste

subscripții sunt atașate contului Microsoft.

În cazul meu, am folosit următoarele facilitați (detaliate în subcapitolele care urmează):

Găzduirea de site-uri web (varianta gratuită)

Găzduirea unui server și baze de date SQL (varianta plătită)

În structura internă a Windows Azure, facilitățile oferite sunt denumite generic Resurse

(spre exemplu serviciul de găzduire a unui site web este o resursa), iar aceste resurse sunt grupate

în Grupuri de Resurse.

1.2.1 Serviciul de Web Hosting

Serviciul de găzduire permite alocarea de spațiu pe un server Microsoft (specificațiile

serverului diferă în funcție de subscripția aleasa), pe care se poate stoca Build-ul cel mai nou al

site-ului web.

Procesul prin care se trimite Build-ul către spațiul de găzduire se numește Publishing, și se

realizează prin intermediul unui fișier de configurare specific numit Publishing Profile (ce conține

date cum ar fi conexiuni opționale cu baze de date, numele de utilizator al administratorului, etc.),

fișier care este generat de către Azure. Aceasta publicare se poate face manual (din Visual Studio),

sau automat, ca și unul din pașii din Build Definition (așa cum am procedat și eu).

Figura 5 - Interfața Portalului Azure

Page 18: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

18

Publicarea automată se executa doar dacă Build-ul a fost executat cu succes, garantând-se

astfel că versiunea curenta a site-ului este una mereu funcționala.

Pe lângă spațiul de stocare pe server, se aloca și o anumita cantitate de resurse (memorie

RAM și procesoare), fie dedicate (întregul server sau întreaga cantitate de resurse este folosită de

un singur site web), fie partajate cu alți utilizatori. De asemenea, se aloca și o adresa DNS pentru

domeniu - în cazul subscripției gratuite, domeniul alocat este un subdomeniu pe unul din site-urile

Microsoft disponibile, iar în cazul subscripțiilor plătite, domeniul poate fi orice nume DNS ales de

utilizator.

În cazul meu, am folosit serviciul de găzduire pentru partea de server a aplicației, care

consta într-un site web cu interfețe de Debug reprezentate prin pagini web (ASP.Net MVC)

împreună cu interfețe REST pentru request-uri web (ASP.Net WebApi).

Adresa web a serverului este http://foodappwebapi.azurewebsites.net/ (azurewebsites.net

fiind domeniul Microsoft la care este atașat subdomeniul meu).

1.2.2 Serverul și baza de date SQL

Din suita de funcționalități oferite de Azure, am ales să folosesc și interacțiunea oferită cu

baze de date SQL (subscripția fiind plătită, neexistând subscripție gratuită).

Figura 6 - Fereastra de Login din SQL Management Studio

Page 19: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

19

Pentru a putea creea o bază de date (de orice natură, nu doar SQL), este necesară întâi

cererea unui server pentru a o găzdui. Subscripțiile oferite pentru servere SQL oferă o multitudine

de configurații diferite, având prețuri pe măsură, care sunt capabile să suporte inclusiv site-uri de

nivel comercial, cu mii și zeci de mii de apeluri pe secundă.

Accesul pe serverul de baze de date se poate face prin intermediul utilitarelor Microsoft

dedicate pentru gestiunea bazelor de date, cum ar fi (în cazul meu) SQL Management Studio 2014

(folosind numele de utilizator și parola setate pentru server în Azure). De aici se pot executa script-

uri SQL cu drepturi de administrator.

De notat este că serverele de baze de date oferă posibilitatea cererii de utilizatori multipli,

fiecare cu drepturi de acces specifice, astfel încât se poate lucra fără probleme în echipă. De

asemenea, serverele sunt protejata de un Firewall, accesul fiind limitat la adresele IP pentru care

se creează excepții portalul Azure.

1.3 NuGet

NuGet este o platformă Microsoft care facilitează distribuirea publică de librării compilate

(pachete DLL). Librăriile NuGet folosesc un format specific de împachetare (DLL-urile ce compun

librăria sunt împachetate folosind utilitarul NuGet, împreună cu un fișier specific de configurare,

pentru a obține un singur fișier ca și output), și sunt administrate în Visual Studio prin intermediul

utilitarului NuGet Package Manager.

Package Manager-ul din Visual Studio este capabil să caute pachete, să le instaleze în

proiecte/soluții, să actualizeze pachetele existente, și să șteargă pachete.

Figura 7 - Object Explorer din SQL Management Studio

Page 20: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

20

Printre multitudinea de librării NuGet existente se regăsesc atât librării create de utilizatori

individuali, cât și librării oficiale create de entități comerciale, cum ar fi spre exemplu:

EntityFramework (librărie pentru interacțiuni cu baze de date) - creată de Microsoft

Newtonsoft JSON (librărie pentru interacțiuni cu fișiere JSON) - creată de Newtonsoft

MVVM Light (framework care facilitează folosirea patternului MVVM în aplicații WPF și

WindowsPhone) - creată de Galasoft (Laurent Bugnion)

Async Operations (framework-ul Async/Await) - creată de Microsoft

System.Net.Http (framework pentru comunicarea HTTP în .Net) - creată de Microsoft

Cele enumerate mai sus sunt printre cele mai populare librării (folosite inclusiv în proiectul

meu). Avantajul oferit de ușurința administrații librăriilor reprezintă un argument foarte solid în

favoarea folosirii sistemului NuGet. Un dezavantaj major însă li reprezintă însuși natura platformei,

anume dependenta de resurse externe (se creează un sentiment de nesiguranța), așa că acest aspect

trebuie mereu luat în considerare în momentul în care se decide folosirea unei librării externe.

Orice dezvoltator poate creea propriul pachet NuGet (accesibil public, sau doar privat),

urmând pașii descriși în documentația oferită de utilitar. În cazul meu, am creat trei pachete NuGet,

pe care le-am refolosit în ecosistemul aplicațiilor (aspecte descrise în detaliu în Capitolul 4 al

lucrării).

1.4 LucidChart

LucidChart este o platformă online care permite cererea rapidă și facilă a diagramelor și

schițelor de diverse tipuri - UML (diagrame de clasă, diagrame de flow, diagrame de stare, etc),

scheme logice, wireframes, mock-upri pentru interfețe grafice, etc. Serviciul este disponibil atât

gratuit, cât și contra cost.

În elaborarea lucrării prezente, am tratat LucidChart ca fiind o sursa unică pentru creare de

documentație, salvata atât online, cât și local, pe repository-ul TFS, documentații dintre care pot să

enumăr:

diagrame de flow pentru server și client

diagrame de arhitectura pentru server și client

diagrama de relație între entitățile bazei de date (ERD)

diagrame de Use Cases pentru server și client

Page 21: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

21

Capitolul 2 – Pattern-uri arhitecturale

În dezvoltarea aplicației atașate lucrării am optat pentru construcția codului din punct de

vedere arhitectural bazându-mă pe pattern-urile arhitecturale cele mai potrivite pentru fiecare

tehnologie în parte, distribuite în felul următor:

Aplicația server – paginile web pentru Debug

o ASP.Net MVC 5

Aplicația server – paginile REST pentru request-uri web

o ASP.Net Web Api 2

Aplicația client pe WindowsPhone

o MVVM

De asemenea, în toate aplicațiile care colaborează pentru construcția ecosistemului existent,

am folosit și pattern-ul Design By Contract (detaliat în cele ce urmează).

2.1 Design By Contract

Design By Contract se refera la folosirea unor anumite convenții în cod, numite generic

Contracte, care specifica anumite condiții de satisfiabili țațe pe care aplicația se angajează să le

îndeplinească.

Asemenea unui contract în lumea de zi cu zi, clauzele contractuale sunt în acest caz

reprezentate de către diverse tipuri de apeluri în cod (Code Contracts). În cazul în care una din

condiții nu este satisfăcuta, aplicația ca și întreg nu satisface contractul.

Foarte important de reținut este faptul că folosirea contractelor în cod nu poate garanta

funcționalitatea corectă a aplicației, ci doar satisfiabilitatea aplicației.

Soluția pe care am ales să o folosesc este o librărie pentru Code Contracts creată de către

Microsoft Research, distribuită sub formă de executabil instalabil.

Odată instalata, librăria oferă accesul la namespace-ul System.Diagnostics.Contracts,

alături de un nou tab în proprietățile proiectului, de unde se poate seta comportamentul sistemului.

Din punct de vedere tehnic, Code Contracts sunt menite să înlocuiască validările și

condiționările în cod bazate pe Block-uri try/catch și if/else cu apeluri manuale pentru aruncarea

excepțiilor (orice Code Contract eșuat arunca o excepție de tip ContractFailed).

Page 22: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

22

Standardizarea tipurilor de excepții aruncate împreună cu sintaxa dedicată pentru apelurile

specifice face ca folosirea Code Contracts mult mai eficienta (și mai ușor de documentat folosind

generatoare de documentație automate) decât abordarea validărilor manuale. În cazul meu, am

folosit cinci tipuri de apeluri de Code Contracts (fiecare tip de apel se potrivește pentru un anumit

scenariu), detaliate în cele ce urmează.

Contract.Requires

Contract.Requires<ExceptionType>(Condition)

Se scrie și se apelează la începutul metodei, înainte de scrierea codului metodei

Figura 8 - Tab-ul pentru configurarea Code Contracts in Visual Studio

Page 23: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

23

Specifica condițiile care trebuie îndeplinite pentru a putea intra în metoda

Contract.Ensures

Contract.Ensures(Condition(Contract.Result<T>()))

Se scrie și se apelează la începutul metodei, înainte de scrierea codului metodei,

obligatoriu după Contract.Requires (data există)

Specifica condițiile pe care metoda se angajează să le îndeplinească la finalul

execuției

Se folosește de metoda Contract.Result<T>() care este un indicator pentru

compilator, ce va fi înlocuit cu rezultatul efectiv al metodei la execuție (T este tipul

returnat de metoda)

Contract.Assume

Contract.Assume(Condition)

Se poate apela oriunde în interiorul unei metode

Se folosește asemenea unui block if/else sau a unui block try/catch

Semnifică faptul că se presupune că o condiție ar trebui să fie îndeplinită

Figura 9 - Exemplu Contract.Requires

Figura 10 - Exemplu Contract.Ensures

Page 24: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

24

Folositor în special atunci când apelam o metoda dintr-o librărie/resursa externa,

asupra căreia nu avem control deplin, putând-ne baza doar pe documentație, care

„presupunem” că este corectă

Contract.Invariant

Contract.Invariant(Condition)

Se apelează în interiorul unei metode care

o Apare o singura data într-o clasă

o Returnează void

o Este decorata cu atributul [ContractInvariantMethod]

Se folosește pentru a marca proprietăți din metoda care sunt invariante (după

apelarea constructorului, nu își schimba valoarea în nici un fel)

Apelul este folosit pentru a înlocui verificările manuale în fiecare metoda, atunci

când se folosește o proprietate la nivel global în clasă

Figura 11 - Exemplu Contract.Assume

Figura 12 - Exemplu Contract.Invariant

Page 25: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

25

Interface Contracts

[ContractClass(typeof(TContractClass))]

[ContractClassFor(typeof(TInterface))]

Mergând pe principiul că fiecare clasă ar trebui să aibă o interfața însoțitoare,

CodeContracts oferă facilitatea de a folosi o a treia clasă, care să stocheze apelurile

de Contract.Requires și Contract.Ensures

Clasa a treia trebuie să îndeplinească următoarele condiții:

o Sa fie o clasă abstracta

o Sa fie decorata cu atributul [ContractClassFor(typeof(TInterface))]

unde TInterface este Interfața

o Sa implementeze interfața

În interiorul clasei pentru contracte, în fiecare metoda implementata din interfața,

se scriu apelurile de contracte, și se returnează default(T) unde T este tipul

returnat de metoda

Interfața trebuie la rândul ei să fie decorata cu atributul

[ContractClass(typeof(TContractClass))] unde TContractClass este clasa

pentru contracte

Prin aceasta abordare se obține o separare între funcționalitatea efectiva a clasei și

elementele de validare (rezultând într-un cod lizibil și ușor de întreținut)

Figura 13 - Exemplu Contracts Class

Page 26: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

26

2.2 MVC

Denumirea MVC este prescurtarea numelui Model–View–Controller, un pattern foarte

des folosit în mediul de dezvoltare Web. Structura de bază se poate observa în figura de mai jos:

Elementele componente au următoarele funcții de bază:

Controller

o Conține logica de business, validări de date, operații de comunicare cu baza

de date, etc.

o Folosește Model-ul pentru a trimite date către View

View

o Afișează datele primite de la Controller (date stocate în Model)

o Nu conține nici un fel de logica de business, ci doar afișează ceea ce primește

Model

o Conține clase cât mai simpliste

o Folosit pentru transfer de date între mediul de stocare permanent și View,

prin intermediul Controller-ului

În cazul meu, am folosit o abordare MVC pentru construirea paginilor web folosite în scop

de Debug în cadrul aplicației server (detalii în subcapitolul 4.2.6).

Figura 14 - Structura MVC

Page 27: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

27

2.3 WebApi

WebApi este o tehnologie construita de către Microsoft, folosită în ecosistemul ASP.Net,

în general. Folosirea terminologiei Api în denumire sugerează că principala funcționalitate a

WebApi este de a creea sisteme tip API, capabile să răspundă la request-uri Web.

Structura de bază se poate observa în figura de mai jos:

Se poate observa că aplicațiile Client apelează serviciul de tip WebApi (prin request-uri

web, de regula REST) pentru a accesa date dintr-o bază de date. Clientul nu apelează în mod direct

baza de date.

Serviciul WebApi se ocupa de comunicația în ambele sensuri, fiind capabil să răspundă la

următoarele tipuri de request-uri:

GET – returnare de date

POST – operațiune de creare a datelor

PUT – operațiune de actualizare a datelor

DELETE – operațiune de ștergere a datelor

Se poate observa că operațiunile suportăte de WebApi sunt de fapt operațiunile standard în

protocolul HTTP.

În cazul meu, am folosit WebApi pentru a creea serviciul REST de acces al datelor din baza

de date de către aplicația client de pe WindowsPhone (detalii în subcapitolul 4.2.7).

Figura 15 - Structura WebApi

Page 28: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

28

2.4 MVVM

MVVM este acronimul pattern-ului Model-View-ViewModel, un pattern foarte des întâlnit

în aplicații bazate pe Windows Presentation Foundation (cum este Windows Phone), și care poate

fi considerat ca o evoluție al MVC-ului.

În figura de mai jos se poate observa formă de bază a pattern-ului:

Asemănător cu MVC, se poate observa prezenta componentelor Model și View, însă

Controller-ul este înlocuit cu o componentă nouă, numita ViewModel. Se poate observa de

asemenea că direcțiile de comunicare sunt schimbate. Diferențele pe care le aduce MVVM sunt

următoarele:

Model-ul nu comunica direct cu View-ul, ci doar cu ViewModel-ul

ViewModel-ul acționează ca și entitate de gestiune a logicii de business

ViewModel-ul expune proprietățile Model-luului către View prin intermediul unor

proprietăți proxy

Modalitatea de funcționare a MVVM-ului se bazează pe notificări, mai mult decât pe

execuții manuale. ViewModel-ul expune o serie de proprietăți către View (spre exemplu un

Model), și se folosește de pattern-ul Observable Object Pattern pentru a reacționa atunci când

starea uneia din proprietăți se schimba pe View.

Figura 16 - Structura MVVM

Page 29: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

29

Logica de business din ViewModel este executata doar în momentul în care se reacționează

la schimbarea stării proprietății (motiv pentru care comunicația între ViewModel și Model este

într-un singur sens – ViewModel-ul transmite data către Model, iar Model-ul doar primește).

În cazul meu, am folosit MVVM în cadrul aplicației scrise pe WindowsPhone, folosind un

framework numit MVVM Light, produs de către compania Galasoft (detalii în subcapitolul 4.4).

Page 30: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

30

Capitolul 3 - Structura și conținutul repository-ului

Pentru stocarea datelor în general (cod, documentație, script-uri, SQL, etc.), am ales, așa

cum am menționat în paginile anterioare, soluția Microsoft numita Team Foundation Server, mai

exact facilitatea care permite subversionare. Procesul de subversionare este procesul prin care se

stochează date în versiuni incrementale, pe măsura ce apar schimbări. Sistemul funcționează pe

ideea cererii de „sub versiuni”, urmând ca fiecare modificare a datelor să creeze o nouă versiune,

lăsând versiunile vechi intacte.

Modelul de subversionare incremental garantează accesul liber la oricare versiune a datelor

din trecut, facilitând:

analiza datelor din punct de vedere evolutiv (se poate observa evoluția datelor prin

analiza diferențelor între versiuni)

posibilitatea de a face pasul înapoi spre date din versiuni anterioare (dacă spre

exemplu cea mai nouă iterație a datelor se dovedește a fi problematica)

Una din facilitățile cele mai des folosite ale sistemelor de subversionare este posibilitatea

de a creea așa numitele Branch-uri (ramuri), care acționează ca și container subordonat

containerului părinte (asemenea sistemului de gestiune al fișierelor în sistemele de operare, unde

există relații de subordonare între directorul copil și directorul părinte). În cazul sistemelor de

subversionare, containerul părinte este numit Repository, și este cel mai înalt nivel al sistemului de

gestiune (directorul părinte).

Repository-urile pot avea date atașate lor în mod direct (asemenea unui fișier individual

într-un director părinte), sau pot avea Branch-uri atașate (asemenea unui director copil într-un

director părinte). Gestiunea se face în mod recursive, astfel încât fiecare Branch poate avea un

număr nelimitat de Branch-uri copil, care la rândul lor pot avea propriile Branch-uri copii (identic

cu gestiunea directoarelor în sistemele de operate).

Cel mai indicat este ca datele să fie partajate în Branch-uri, și să nu fie atașate în mod direct

Repository-ului. O structura ideala de Branch-uri ar putea fi în felul următor:

Un Branch de development – pentru datele asupra cărora s-a încheiat lucrul și sunt

gata de testare

Un Branch de release – pentru datele care au fost testate și sunt pregătite să fie

trimise în producție

Page 31: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

31

Cate un Branch individual pentru fiecare facilitate la care se lucrează (fiecare

facilitate nouă creează un Branch nou)

Important de menționat este faptul între Branch-uri se pot executa o serie de operațiuni,

care facilitează transferul de date:

Merge – unirea a doua Branch-uri

Create – cererea unui Branch nou

Delete – ștergerea unui Branch

Indicat este ca în momentul în care s-a încheiat treaba pe un Branch nou, să se facă

operațiunea de Merge cu Branch-ul de development, apoi să se execute operațiunea de Delete

asupra Branch-ului. Managementul Repository-ului se poate face fie online (din TFS online), fie

direct din Visual Studio (folosind componentă numita Team Explorer). În cazul meu, am optat

pentru managementul direct din Visual Studio:

Figura 17 - Team Explorer in Visual Studio

Page 32: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

32

Din punct de vedere al organizării Branch-urilor, eu personal am optat pentru un singur

Branch de development, pentru fiecare proiect din Repository, la care s-au mai adăugat Branch-uri

dedicate stocării datelor adiacente, cum se poate observa în figura de mai jos:

Componenta Repository-ului meu poate fi suma rizata în felul următor:

dlargu.visualstudio.com\dlargu

o Reprezintă adresa serverului pe care este găzduit Repository-ul

FoodApp

o Este numele Repository-ului și totodată indica nivelul cel mai înalt în

sistemul de gestiune

BuildProcessTemplates

o Este un director creat automat de către TFS pentru stocarea template-urilor

pentru definițiile de Build XAML

DatabaseScripts

o Branch creat pentru stocarea script-urilor SQL

Creerea bazei de date

Upgrade-ul baze de date

Figura 18 - Structura Repository-ului

Page 33: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

33

Inserție de date

DIContainer

o Conține soluția pentru proiectul containerul ului de dependințe (detalii în

subcapitolul 4.1)

o Denumirea vine de la DependencyInjection Container

o Soluția este scrisa în .Net Portabil (portable class library)

Docs

o Conține documentația atașata lucrării

DegreePaper

Documente adiacente acestei lucrări (documente individuale

importate din Google Drive)

Lucrarea în sine (acest document)

o PhoneApp

Diagrame de flow, de arhitectura și Use Cases

Mockup-urile ecranelor

o WebApi

Diagrame de flow, de arhitectura și Use Cases

Diagrama bazei de date (ERD) și o copie a diagramei EDMX

(generata automat în Visual Studio)

o De asemenea, în acest Branch se găsește și documentul unde este scrisa

propunerea originala a lucrării de licenţă (ideea inițiala, asupra căreia s-au

făcut modificări în timp)

NuGet Packages

o Conține pachetele NuGet în formă finală, pregătite pentru a fi publicate pe

site-ul NuGet

Pachet pentru DIContainer

Pachet pentru OperationsApi

Pachet pentru WebApiModels

OperationsApi

o Conține soluția pentru proiectul Proxy, care intermediază comunicarea între

Server și Client (detalii în subcapitolul 4.3)

o Soluția este scrisa în .Net Portabil (portable class library)

Page 34: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

34

PhoneApp

o Conține soluția pentru proiectele ce compun aplicația pentru telefonul mobil

scrisa în WindowsPhone (detalii în subcapitolul 4.4)

WebApi

o Conține soluția pentru proiectele ce compun aplicația server (detalii în

subcapitolul 4.2)

Am optat pentru folosirea acestei abordări din cauza garanției securității datelor pe care o

oferă, nefiind nevoie ca eu personal să mă ocup de subversionare manuala, sau de backup-ul datelor

în locații diferite.

Scrierea datelor în Repository se realizează prin operațiunea de Checkin din Visual Studio

(fiecare Checkin fiind atașat unui PBI, așa cum am menționat în discuția despre Backlog din primul

capitol al lucrării), iar fiecare Checkin pornește în mod automat Build Agent-ul care rulează Build

Definition-ul specific pentru a creea un Build. Datele ajung în Repository doar dacă Build-ul a

trecut cu succes (facilitate oferită de Gated Checkins).

De menționat este și faptul că pentru a putea lucra cu proiectul, trebuie executata

operațiunea de Checkout asupra Repository-ului, care practic realizează o copie locala a datelor

prezente pe server. În Figura 17 - Team Explorer în Visual Studio se poate observa o secțiune numita Pending

Changes – aceasta secțiune este practic cea responsabilă pentru a identifica diferențele între

versiunea datelor de pe server și versiunea datelor locale. Diferențele identificate reprezintă

fișierele ce pot compune un Checkin.

Un avantaj deosebit de important în folosirea subversionarii li reprezintă însuși caracterul

evolutiv al analizei datelor. Vizualizând istoria fiecărui fișier, se pot observa schimbările în timp

ale datelor, ducând la minimizarea riscului de pierdere a datelor importante, la care se adaugă și

cuplarea fiecărui Checkin cu PBI-ul corespunzător, ducând astfel la o buna înțelegere a motivației

existentei datelor din Repository în orice moment.

Page 35: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

35

Capitolul 4 - Proiectele create

Partea practica a acestei lucrări este compusa dintr-o serie de aplicații software, care

funcționează într-un ecosistem interdependent pentru a creea funcționalitatea finală. Aplicațiile

componente sunt scrise în framework-ul .Net și limbajul C#, folosind mediul de programare Visual

Studio.

Fiind un ecosistem creat în .Net folosind Visual Studio, fiecare aplicație este reprezentată

ca și o Soluție, compusa din unul sau mai multe Proiecte. Aceasta Soluție este de fapt un fișier

XML cu format specific, pe care Visual Studio li interpretează pentru a vedea ce proiecte trebuie

incluse, compilate și rulate, și în ce ordine. Codul propriu-zis se regăsește în interiorul fiecărui

proiect.

Structurarea proiectelor ar trebui în mod idea să urmeze principiul Separation of Concerns

(separarea atribuțiunilor, sau a rolurilor), astfel încât fiecare proiect să aibă un rol bine definit, cât

se poate de unitar.

Spre exemplu, ideal ar fi ca într-un sistem unde există comunicație cu un serviciu extern,

procesul efectiv de comunicare să fie segregat într-un proiect dedicat, procesul de validare a datelor

și pregătire pentru afișare să fie segregate într-un alt proiect, și afișarea în sine să fie din nou, alt

proiect.

În cazul meu, structurarea proiectelor am realizat-o urmând exact acest principiu, încărcând

cât mai mult să separ funcționalitățile între ele.

Din punct de vedere al aplicațiilor componente, ecosistemul meu se compune din patru

aplicații (detaliate în cele ce urmează):

DIContainer

FoodAppWebApi

FoodAppOperationApi

FoodAppPhoneApp

Page 36: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

36

4.1 DIContainer

Aplicația componentă DIContainer reprezintă un container de dependințe creat sub formă

unei librării portabile. Motivația principala pentru existenta acestei aplicații este posibilitatea de a

folosi DependencyInjection în celelalte aplicații componente, apelând la serviciul NuGet pentru

transmiterea pachetului. Containerul de dependințe reprezintă concret un dicționar care poate

conecta fie o interfața de o clasă (marcând clasa ca fiind explicit legată de interfața), fie o interfața

de o clasă instanțiată (marcând clasa instanțiată ca fiind explicit legată de interfața).

În cadrul celorlalte aplicații componente, containerul se folosește pentru a gestiona

dependințele claselor de interfețe, folosind doua abordări simultane (folosind metodele oferite de

acest proiect):

Cuplarea dependințelor

Rezolvarea dependințelor

Finalitatea o reprezintă posibilitatea ca în orice sector de cod ne-am afla, să putem avea

acces direct la o instanța gata pregătită a oricărei clase avem nevoie, prin preferențierea interfeței

sale. Aceasta maniera de lucru se bazează și pe singularitatea containerului în aplicația care li

folosește (folosind pattern-ul Singleton).

4.1.1 Detalii arhitecturale

Din punct de vedere al organizării proiectelor, soluția aferenta are următoarea structura:

Figura 19 - Structura soluției DIContainer

Page 37: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

37

Aceste trei proiecte au următoarea funcționalitate:

FoodAppDIContainer.Console

o Conține un proiect de tip consola, folosită pentru a verifica rapid un scenariu

de test

FoodAppDIContainer.PortableCore

o Proiect de tip Portable Class Library, ce conține codul funcțional

o Funcționalitatea este expusa prin intermediul interfeței IDIContainer

FoodAppDIContainer.PortableCore.UnitTests

o Proiect de tip Unit Test

o Folosit pentru testarea containerului

Interfața publica IDIContainer expune următoarele metode:

IDIContainer RegisterType<TFrom, TTo>() where TTo : TFrom;

o Tipul returnat este tipul containerului

o Se folosește pentru a înregistra o legătura între doua tipuri care îndeplinesc

constrângerea de moștenire TTo : TFrom (ceea ce înseamnă că TFrom este

interfața, iar TTo este clasă)

IDIContainer RegisterType<TFrom, TTo>(string p_Name) where TTo :

TFrom;

o Aceeași funcționalitate ca și metoda precedentă, însă cu un adaos foarte

folositor – legătura creată este identificata pe baza unui nume transmis ca

parametru (ajuta atunci când o interfața este folosită în mai multe clase)

IDIContainer RegisterInstance<TInterface>(TInterface p_Instance);

o Se folosește pentru a înregistra o legătura între instanța unei clase și o

interfața

o Se poate observa că instanța clasei este de tipul interfeței, ceea ce obliga să

existe o relație de moștenire între clasa instanțiată și interfața (altfel

înlocuirea tipurilor nu este permisa de către compilator)

T Resolve<T>();

o Se folosește pentru a returna o instanța de tipul T

o Parametrul generic este tipul interfeței (cu care s-a realizat în prealabil

cuplajul folosind una din metodele anterioare), iar tipul returnat este tot

Page 38: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

38

tipul interfeței (ceea ce din nou, obliga existenta unei relații de moștenire

între clasă și interfața)

T Resolve<T>(string p_Name);

o Aceeași funcționalitate ca și metoda precedentă, însă de aceasta data

instanța este identificata după nume (folosindu-se în prealabil metoda

corespunzătoare pentru înregistrarea cuplajului)

Important de menționat este că acest proiect oferă funcționalitatea de bază a containerului,

modalitatea de folosire fiind la latitudinea fiecărei aplicații în parte.

În cazul meu, în fiecare aplicație am creat un proiect dedicat care preferențiază containerul,

cu un Wrapper peste interfața expusa (astfel încât referința externa să aibă un singur punct de intrare

în fiecare aplicație, și referințele interne să fie asupra Wrapper-ului). În interiorul Wrapper-ului am

expus o proprietate de tipul containerului, care respectă pattern-ul Singleton, astfel asigurându-

mă că în orice moment există o singura instanța a containerului.

Fiecare proiect utilitar din cadrul fiecărei soluții are câte o clasă dedicată unde se creează

cuplajele pentru tipurile și instanțele din acel proiect, iar proiectul principal (punctul de intrare din

aplicație) conține o clasă unde care apelează toate aceste clase din proiectele utilitare.

În momentul în care este necesară o instanța a unei clase, se apelează proprietatea expusa

de către Wrapper.

4.1.2 Unit Testing folosind Mock-uri

Pentru unit teste am folosit librăria specializata Moq6 pentru a creea un mock al

containerului pe care se pot executa teste.

Mock-urile reprezintă practic instanțe ale unui tip de date, care au atașate anumite

configurări pentru comportamentul obiectelor (se poate configura o metoda să returneze o anumita

valoare). Aceste instanțe sunt păstrate într-un container static care cărui perioada de viată este egala

cu perioada de viată a clase de test.

Ideea din spatele aceste abordări este de a testa comportamentul unitar al unei clase,

abstractizând detaliile de implementare și presupunând că elemente adiacente funcționează într-un

anumit fel (mai exact în maniera descrisa de setările mock-urilor).

6 Moq NuGet - https://www.nuget.org/packages/Moq/ (http://www.moqthis.com/)

Page 39: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

39

Un exemplu foarte bun este testarea unei metode atașate unui Controller în MVC.

Presupunem că aceasta metoda apelează un serviciu de baze de date pentru a aduna date, executa

operațiuni asupra lor, și le pasează mai departe unui View pentru a fi afișate. Ce ne interesează pe

noi să testam este partea asupra căreia Controller-ul este proprietar, așa că vom folosi mock-uri

pentru a emula comportamentul care aduna datele și comportamentul care afișează datele.

Ideal ar fi ca fiecare metoda să aibă câte o configurare pregătită pentru fiecare varianta de

comportament. Folosind comportamentul de mai sus, am avea o setare pentru situația în care

adunam datele cu succes, și o setare pentru situația în care adunarea de date eșuează. Folosind

aceste setări, putem testa comportamentul Controller-ului în situațiile respective.

Aceasta abordare respectă regulile de bază ale unit testelor, și anume:

Un unit test nu ar trebui să lucreze vreodată cu date reale și să afecteze în vreun fel

tangibil sistemul (de exemplu niciodată un unit test nu ar trebui să aibă voie să scrie

date în baza de date)

Un unit test ar trebui să testeze lucruri unitare (lucruri mărunte, nu funcționalități

mari)

În cadrul acestui proiect, m-am folosit de mock-uri pentru a creea instanțe și clase și a testa

comportamentul în situații pozitive (flow normal – înregistrare și rezolvare corectă) și în situații

negative (flow anormal – spre exemplu încercam să rezolvam o clasă care nu a fost înregistrata).

De menționat este că execuția acestor unit teste este trecută ca și pas în Build Definition-ul

atașat proiectului (în acest caz un Build XAML cu Gated Checkin activat), însemnând că este

obligatoriu ca orice nouă schimbare de cod să nu strice în vreun fel funcționalitatea existenta.

4.1.3 Portabilitatea soluției

Soluția a fost creată din start ca și librărie portabila, însemnând că poate fi folosită în orice

proiect de orice fel, bazat pe .Net (evident, are acces la un subset limitat din funcționalitățile .Net,

mai exact acele elemente comune între toate platformele).

Fiind un proiect care este folosit în toate celelalte aplicații, am decis să creez un pachet

NuGet folosind metodologia specifica7 și să preferențiez acest pachet8 folosind NuGet Package

Manager în fiecare proiect, în loc să folosesc referințe directe.

7 Ghidul de creare a unui pachet NuGet - https://docs.nuget.org/create/creating-and-publishing-a-package 8 Pachetul se găsește public la adresa - https://www.nuget.org/packages/FoodAppPortableDIContainer/

Page 40: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

40

4.2 FoodAppWebApi

Soluția FoodAppWebApi conține proiectele ce compun aplicația componentă pentru Server.

În cadrul aceste soluții am dorit să creez un ecosistem de sine stătător, care să poată fi găzduit

folosind orice serviciu care accepta aplicații .Net, particular ASP.Net, cum ar fi în acest cazul

Windows Azure.

Așa cum am explicat în subcapitolele anterioare, aceasta aplicație este găzduita pe

Windows Azure, folosind o subscripție gratuită, ce permite accesul de pe un subdomeniu asignat.

Toate request-urile și operațiunile ce implica serverul se executa folosind aplicația existenta

la adresa oferită de către Windows Azure, astfel încât serverul este practic mereu disponibil (nu

trebuie rulat manual pentru a accepta operațiuni).

În dezvoltarea serverului, am avut acces la întregul framework .Net (spre deosebire de

proiectele Portable Library și WindowsPhone, care au acces doar la subseturi din framework-ul

.Net).

De asemenea, am urmărit exemplificarea folosirii codului într-o maniera cât mai

abstractizata și segregata cu putința (detalii în subcapitolul următor), încercând să introduc un nivel

cât mai mare de lucru cu date de tipuri generice.

De notat este faptul că elementele interne ale proiectului sunt reutilizabile, indiferent de

tehnologia în care este scrisa secțiunea care asigura conexiunea cu lumea exterioara (spre exemplu

partea de REST și Debug poate fi scrisa cu ușurința în Java, refolosind pârțile componente ale

proiectului).

Acest lucru se aplica și bazei de date, care poate fi găzduita pe orice server, și folosind orice

tehnologie SGBD (.Net este capabil, într-o formă sau alta, să lucreze cu aproximativ orice fel de

tehnologie pentru baze de date). Folosind script-urile SQL prezente în Repository, se poate creea

o nouă bază de date oriunde.

Page 41: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

41

4.2.1 Detalii arhitecturale

Din punct de vedere arhitectural, soluția este organizata în felul următor:

Funcționalitățile proiectelor sunt împărțite în secțiuni (marcate drept foldere de soluție în

Visual Studio, având corespondente foldere fizice în Repository), în funcție de zona aria de interes

și în funcție de zona cu care se lucrează.

Se poate observa de asemenea că denumirile proiectelor sunt compuse din numele soluției,

urmat de numele zonei, urmat de numele efectiv al proiectului, bazat pe funcționalitatea sa.

Maniera aceasta de abordare, deși aparent greoaie, ajuta foarte mult la înțelegerea structurii și

funcționalității proiectelor, fără a fi nevoie de o analiză a codului.

Figura 20 - Structura soluției FoodAppWebApi

Page 42: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

42

Zona DependencyContainer

Aici întâlnim proiectul Wrapper pentru librăria DIContainer, așa cum am menționat în

subcapitolul 4.1. De menționat este că acest proiect este referențiat în toate proiectele din aceasta

soluție care folosesc DependencyInjection, fiecare proiect având o clasă numita Assembler pentru

înregistrarea dependințelor, clasă ce moștenește interfața IAssembler, expusa de către acest

proiect.

Zona Common

Aceasta zona este rezervata pentru proiecte ce conțin clase de tip POCO9, care sunt

refolosite în interiorul aplicației. Fiecare proiect din aceasta zona este un proiect de sine stătător,

care nu referențiază nici un alt proiect (ci este doar el referențiat).

Proiectele componente sunt următoarele:

FoodApiWebApi.Common.Constants

o Acest proiect conține clase ce expun date constante

O clasă pentru String-uri constante folosite în aplicație (exemplu

mesajele returnate în urma efectuării unei operațiuni)

Clase pentru elemente de interfața pentru meniurile din pagini)

FoodApiWebApi.Common.Models (Portable Class Library)

o Acest proiect conține Modelele folosite în aplicație

o Modelele sunt folosite pentru a transfera date de la baza de date către restul

aplicației (adaptând Entitățile la Modele, folosind pattern-ul Adapter)

FoodApiWebApi.Common.ViewModels

o Aceasta aplicație conține clase POCO care expun proprietăți ce sunt folosite

exclusiv în View-urile de Debug ale aplicației (identice cu cele din Modele)

o Fiind folosite într-un mediu ASP.Net, proprietățile acestor clase sunt

decorate cu atribute specifice aplicațiile ASP.Net (atribute care au rol de

validare a datelor)

o Transferul datelor între Models și ViewModels se face tot prin intermediul

pattern-ului Adapter

9 POCO – Plain Old CLR Object – abreviere pentru clase simpliste, care expun proprietăți, însă nu conțin logica

complexa, si sunt adesea folosite ca entități de transfer pentru transferul de date intre nivele ale aplicației.

Page 43: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

43

Zona Backend

În aceasta zona întâlnim proiectele care se ocupa de comunicația cu baza de date, oferind

funcționalitatea de citire și scriere, și transferând datele mai departe în aplicație.

Proiectele componente sunt următoarele:

FoodAppWebApi.Backend.Mappers

o Acest proiect conține configurările pentru mapările folosite atunci când se

dorește transformarea unui obiect dintr-un tip în alt tip, folosit librăria

specializata numita AutoMapper10

o Configurările din acest proiect sunt aplicate pentru operațiuni între

Entities, Models și ViewModels

o Disponibilitatea configurărilor este globala în întregul proiect, în mod static

FoodAppWebApi.Backend.Adapters

o Acest proiect se ocupa de adaptarea efectiva a tipurilor de date, folosind

configurările existente în proiectul FoodAppWebApi.Backend.Mappers și

librăria AutoMapper, urmând procedura sugerata de către pattern-ul

Adapter (atât asupra obiectelor individuale, cât și asupra listelor)

o Exista doua tipuri de transformări suportăte

ModelToEntity și EntityToModel

ModelToViewModel și ViewModelToModel

FoodAppWebApi.Backend.DBEntities

o Acest proiect conține modelul bazei de date în format EDMX11, folosind

EntityFramework12 și abordarea DatabaseFirst13

FoodAppWebApi.Backend.DAL.DataRetreiver

o Acest proiect face parte dintr-o sub-arie numita DAL14

o Se ocupa de operațiunile de citire a bazei de date și de adunare de informații

(echivalentul în HTTP al operațiunilor de tip GET)

10 AutoMapper - http://automapper.org/ 11 EDMX – Fișier XML ce conține informații legate de baza de date (tabele, proprietăți, relații, etc), folosit de către

EntityFramework pentru a genera entitățile, si interpretat in Visual Studio in format grafic 12 EntityFramework – Una din soluțiile celor de la Microsoft pentru lucrul cu baze de date, acționează ca un Wrapper

peste funcționalitățile SQL – https://www.nuget.org/packages/EntityFramework 13 DatabaseFirst – una din variantele posibile prin care EntityFramework poate general fișierul EDMX – in aceasta

situație se pornește de la o baza de date deja existenta pe un server 14 DAL – Data Access Layer – denumire standard pentru proiectele care efectuează transfer de date

Page 44: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

44

FoodAppWebApi.Backend.DAL.DataSender

o Face parte de asemenea din sub-aria DAL

o Se ocupa de operațiunile de scriere în baza de date (echivalentul în HTTP al

operațiunilor de tip POST, PUT și DELETE)

În afara unei zone specifice se afla și proiectul principal al soluției, care asigura

comunicarea cu exteriorul, în acest caz un proiect de tip ASP.Net MVC și WebApi, numit

FoodAppWebApi.Portal.

Acest proiect nu este inclus într-o zona specifica tocmai pentru a accentua faptul că poate

fi oricând înlocuit cu alt tip de proiect, fără a fi nevoie de rescrierea celorlalte zone. Spre exemplu

dacă s-ar dori ca serverul să nu fie aplicație web, ci o aplicație desktop, atunci aceasta aplicație s-

ar putea înlocui cu o aplicație WPF, și cu un minim de efort (refacere a referințelor), am avea un

nou FrontEnd (care evident va trebui să conțină codul necesar pentru a fi funcțional).

Serverul este găzduit pe Windows Azure, așa cum am menționat și mai devreme, în

principal prin prisma facilitaților oferite de către Windows Azure, pe care eu personal le-am folosit

așa cum este detaliat și în Diagrama Use Case expusa în continuare:

Figura 21 - Operațiunile folosite in Azure Cloud

Page 45: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

45

Per total, serverul este construit de așa natura încât să suporte următoarele operațiuni,

detaliate în Diagrama Use Case de mai jos:

Figura 22 - Operațiuni suportate de către server

Page 46: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

46

Arhitectura în general a aplicației server poate fi suma rizata în Diagrama Arhitecturala

următoare:

Urmărind aceasta arhitectura, observam că există doua secțiuni separate în ecosistemul

aplicației FrontEnd:

View-urile pentru Debug

o Sunt scrise în ASP.Net MVC

o Sunt pagini web tangibile, expuse în scopuri administrative

Metode pentru API-ul REST

o Sunt scrise în ASP.Net WebApi

o Asigura punctul de acces pentru aplicațiile ce se folosesc de API-ul REST

Ambele secțiuni expun datele existente în baza de date și operațiuni care permit

manipularea lor (Debug Views prin intermediul paginilor web ce conțin formulare web, iar API-ul

REST prin intermediul request-urilor HTTP). Exista și aici o separare clara a direcției în care se

executa operațiunile, existând un flow separat pentru citire și unul separat pentru scriere.

Figura 23 - Arhitectura serverului

Page 47: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

47

Flow-ul pentru operațiuni de citire (echivalente HTTP GET) este expus în următoarea

Diagrama de Flow:

Figura 24 - Flow-ul operațiunilor de citire

Page 48: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

48

Flow-ul pentru operațiunile de scriere (echivalentul HTTP POST/PUT/DELETE) este expus

în următoarea Diagrama de Flow:

Pe întreg pârșul dezvoltării serverului am urmărit cererea unor segmente de cod cât mai

generice și mai reutilizabile, respectând cât se poate de mult următoarele reguli:

Interfețele să fie cât mai segregate și simpliste

o Se impune separarea funcționalităților, astfel încât să se evite repetarea

funcționalităților

o Am insistat pe crearea de operațiuni unitare, în sensul de funcționalități mici

care împreună creează funcționalități mari (în loc de funcționalități mari

dintr-o bucata)

o Ajuta la re-utilizarea codului

Am separat codul comun în operațiuni bazate pe tipuri de date generice

o Spre exemplu, o mare parte din operațiunile cu baza de date sunt comune

între toate tipurile de date

Figura 25 - Flow-ul operațiunilor de scriere

Page 49: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

49

Am separat funcționalitățile de tip ”funcționalități de bază” în clase abstracte

standardizate numite Base Classes

Am folosit Code Contracts pentru siguranța codului

Am creat cât mai puține legături între elementele din proiect, mergând pe principiul

claselor Loosely Coupled

Din punct de vedere al scrierii codului, am urmat regulile propriului meu Coding

Style (prezent în toate proiectele)

Din considerente arhitecturale, acest proiect este suficient de separabil încât să suporte cu

ușurința modificări pe viitor, ceea ce a și fost unul din principalele mele obiective.

4.2.2 Baza de date

Baza de date este găzduita în Windows Azure (așa cum am menționat în subcapitolele

anterioare), și poate fi cu ușurința transferata pe orice alt serviciu de găzduire prin simpla executare

a Script-urilor SQL prezente în Repository.

Din punct de vedere arhitectural, Diagrama ERD15 a baze de date arata în felul următor:

15 ERD – Entity Relationship Diagram – diagrama ce descrie entitățile unei baze de date, alături de relațiile dintre ele

Figura 26 - Diagrama ERD a bazei de date

Page 50: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

50

Prin folosirea EntityFramework și abordarea DatabaseFirst, în Visual Studio se generează

un fișier EDMX ce conține clasele C# corespunzătoare entităților bazei de date, alături de o

diagrama în format grafic, care arata în felul următor (foarte asemănătoare cu ERD-ul):

De menționat este și faptul că, prin prisma EntityFramework, în interiorul proiectelor

FoodAppWebApi.Backend.DAL.DataRetreiver și FoodAppWebApi.Backend.DAL.DataSender

am folosit pattern-ul Repository, pattern specific lucrului cu EntityFramework, care permite

execuția de operațiuni generice asupra bazei de date.

Concret, în loc să trebuiască menționat în mod explicit că o operațiune se executa asupra

unui tip anume (spre exemplu o operațiune de Create executata pe o data de tip Ingredient),

operațiunea se poate executa pe un tip generic T, urmând ca EntityFramework să își dea seama

când rulează ce fel de date sunt de fapt prezente.

Prin intermediul acestei abordări, alături de abordarea de segregare a interfețelor și folosire

a claselor de bază, am realizat în mod generic o parte din operațiunile folosite:

GetAll – pentru returnarea de date

Figura 27 - Diagrama EDMX în Visual Studio

Page 51: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

51

Exists – pentru a verifica dacă o înregistrare există

Create – pentru crearea unei înregistrări

Update – pentru actualizarea unei înregistrări

Delete – pentru ștergerea unei înregistrări

BatchCreate – pentru crearea mai multor înregistrări deodată

Operațiuni mai specifice (cum ar fi spre exemplu returnarea ingredientelor care fac parte

dintr-o rețeta – și în general operațiunile care se bazează pe relații) au fost executate folosind

referențierea directa a tipului, pentru că altfel nu se putea aborda relația bazată pe Foreign Keys

în EntityFramework (fără a ști concret tipul datelor nu se poate construi relația).

Chiar și cu limitarea cauzata de relațiile între entități, folosirea datelor generice micșorează

mult cantitatea de cod necesară și reduce dramatic cantitatea de cod care se repeta (fără aceasta

abordare ar fi trebuit ca aceste operațiuni să fie repetate pentru fiecare tip de data, cu diferențe

minuscule).

Un alt aspect important de menționat este că toate operațiunile de scriere asupra bazei de

date le-am executat folosind EntityFramework Transactions, care folosesc pe fundal

tranzacțiile din SQL. Ideea din spate este că operațiunile executate nu modifica imediat baza de

date, ci sunt segregate într-o tranzacție, iar dacă tranzacția se executa cu succes, atunci și baza de

date se modifica, altfel schimbările sunt propagate, iar baza de date rămâne neschimbata.

Un exemplu des întâlnit unde tranzacțiile sunt de un real ajutor este situația în care trebuie

ștearsa o entitate și toate legăturile dintre ea și alte entități (și în general orice operațiuni unde sunt

implicate mai multe entități – situație des întâlnita și în cazul meu). Ștergerea se face iterativ (întâi

se șterg relațiile, apoi entitatea), iar dacă spre exemplu unul din pașii iterativi eșuează, în lipsa unei

tranzacții, ștergerea nu s-ar efectua corect și ar rămâne în urma date potențial dăunătoare pentru

baza de date (entități orfane).

Prin folosirea tranzacțiilor se asigura execuția curata a operațiunilor, astfel încât orice

operațiune eșuata nu afectează baza de date.

4.2.3 Portabilitatea Modelelor

Așa cum am explicat în discuția arhitecturala, proiectul ce conține Modelele este un proiect

de tip Portable Class Library.

Page 52: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

52

Motivația din spate acestui fapt este că Modelele sunt folosite în toate aplicațiile care depind

de server, într-o formă sau alta, așa că s-a impus necesitatea distribuirii lor.

În exact aceeași maniera ca și în cazul aplicației DIContainer, am decis să creez un pachet

NuGet16 prin care să distribui și proiectul FoodApiWebApi.Common.Models, în domeniul public.

4.3 FoodAppOperationApi

Acest proiect acționează ca intermediar între server și client, permițând încapsularea

serverului, astfel încât acesta să nu fie accesat în mod direct de către client.

4.3.1 Design și motivație

În vederea respectării tipologiei multi-nivel, nu am dorit să permit comunicarea directa între

entitățile ce stochează date și entitățile ce afișează date (așa cum și în aplicația server spre exemplu

baza de date nu este accesata direct de către proiectul FrontEnd, ci orice comunicație se executa

prin intermediul proiectelor din sub-aria DAL).

Aceasta abordare permite ca serverul să fie complet independent de client, și invers. Singura

condiție obligatorie este ca serverul să expună metodele pe care le transmite mai departe aceasta

aplicație intermediara.

Avantajul este ca serverul poate avea alta găzduire, și chiar și alta tehnologie, fără a afecta

clientul. Prin prisma expunerii datelor folosind REST (prin protocolul HTTP), generatorul

răspunsurilor nu este relevant, atâta timp cât se respectă protocolul.

Similar, din punct de vedere al clientului, acesta poate fi de orice tip, atâta timp cât se

folosește de aplicația intermediara, deoarece prin prisma încapsulării accesului la server, clientul

trebuie doar să fie capabil să trimită și să citească date prin request-uri REST (ceea ce este posibil

în orice tehnologie actuala).

De menționat este ca aceasta aplicație intermediara este scrisa în .Net folosind subsetul .Net

Portabil, așa că accesul efectiv la metodele expuse de către server este condiționat de către acest

aspect.

Prin încapsularea accesului, toate operațiunile efective sunt păstrate în aceasta aplicație:

Pregătirea datelor pentru trimitere

16 Pachetul se găsește public la adresa - https://www.nuget.org/packages/FoodAppModels/

Page 53: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

53

Trimiterea request-ului

Primirea răspunsului

Extragerea datelor din răspuns

Trimiterea rezultatului mai departe

În cazul de fata, aceasta aplicație intermediara folosește formatul de date JSON17 pentru a

comunica cu serverul (folosind librăria JSON.Net18).

O listare a operațiunilor suportăte de aceasta aplicație se poate observa mai jos:

17 JSON – JavaScript Object Notation – tip de date asemănător cu XML, al cărui stil de scriere se aseamănă cu notația

obiectelor de tip Array in JavaScript 18 JSON.Net – Librărie dedicată lucrului cu JSON in .Net, dezvoltata de compania Newtonsoft, disponibila fie pe

NuGet la adresa https://www.nuget.org/packages/Newtonsoft.Json fie la adresa http://www.newtonsoft.com/json

Figura 28 - Operațiunile expuse de către OperationsApi

Page 54: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

54

4.3.2 Portabilitatea soluției

Așa cum am menționat mai devreme, aceasta aplicație este destinata folosirii de către orice

client care dorește să interacționeze cu serverul (din acest considerent, aplicația este de tip Portable

Class Library). La fel ca și în cazurile precedente, am creat un pachet NuGet pe care l-am publicat19,

astfel încă să poată fi descărcat folosind NuGet Package Manager.

4.4 FoodAppPhoneApp

Aceasta este aplicația client, care în ecosistemul creat acționează ca și FrontEnd pentru

server (care poate fi considerat ca și Backend).

4.4.1 Detalii arhitecturale

Aplicația este implementata în WindowsPhone, versiunea 8.1, putând fi oricând publicata

pe Windows Store, și instalabila pe telefoane ce conțin WindowsPhone 8.1 sau Windows 10 Mobile

(Windows 10 Mobile este capabil să ruleze și aplicații scrise în WindowsPhone 8.1).

Organizarea soluției se poate observa mai jos:

19 Pachetul se găsește public la adresa - https://www.nuget.org/packages/FoodAppOperationsApi/

Figura 29 - Structura soluției FoodAppPhoneApp

Page 55: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

55

Cum se poate observa, proiectele care compun soluția sunt următoarele:

FoodAppPhoneApp.DIContainer

o Conține Wrapper-ul pentru DIContainer, exact aceeași idee ca și în cazul

wrapperului existent în FoodAppWebApi

FoodAppPhoneApp.Utils

o Conține clase utilitare

O clasă de String-uri constante

Un Wrapper peste LocalStorage (care ușurează accesul)

O clasă statică cu metode utilitare pentru diverse operațiuni comune

PhoneApplication

o Aplicația de FrontEnd

o Conține codul executabil pentru WindowsPhone (Views, ViewModels,

Convertoare, etc.)

Ca și pattern arhitectural am folosit MVVM, folosind framework-ul MVVM Light20, care

oferă câteva facilitați foarte folositoare (cu ar fi accesul la o clasă de bază pentru ViewModels

numita ViewModelBase, cuplarea între Behaviours din XAML și RelayCommands în

ViewModels, etc.).

Din aceste considerente, trebuie reamintit că în ecosistemul MVVM, ViewModel are

semnificație relativ asemănătoare cu Controller în ecosistemul MVC.

De menționat este că am folosit aplicația OprationsApi și sub-aplicația Models din cadrul

WebApi prin intermediul NuGet Package Manager.

Toate operațiunile se desfășoară în mod asincron, folosind pattern-ul Async/Await, astfel

încât interfața să nu fie blocata pentru utilizator (se afișează în schimb un overlay ce afișează un

mesaj de încărcare și o animație de progres). Foarte important de notat este că suportul pentru

operații asincrone trebuie implementat pana la cel mai jos nivel, de aceea toate operațiunile din

OperationsApi și toate operațiunile pe baza de date din FoodAppWebApi sunt de asemenea

asincrone (altfel întregul lanț nu ar fi asincron).

20 MVVM Light – framework produs de compania Galasoft (Laurent Bugnion) – http://www.mvvmlight.net/

Page 56: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

56

Aplicația client a fost gândita pentru oferi facilitățile generale expuse în următoarea

Diagrama Use Case (în interacțiunea cu rețete și ingrediente):

De asemenea, la aceste facilitați se adaugă și următoarele, relative la interacțiunea cu

utilizatorii aplicației (o parte din operațiuni sunt permise doar administratorului, folosind serverul

în mod direct):

Figura 30 – Relaționarea cu Ingrediente si Reţete în PhoneApp

Figura 31 – Relaționarea cu Utilizatori în PhoneApp

Page 57: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

57

De asemenea, aceasta aplicație este construita pe baza specificațiilor arhitecturale descrise

în următoarea Diagrama de Arhitectura:

Se poate observa că aplicația PhoneApp conține de fapt doua secțiuni, sau module:

Modulul Utilizatorilor

o Suporta următoarele operațiuni:

Login (ecran dedicat)

Logout (accesibil din meniu oriunde în aplicație, după Login)

Register (ecran dedicat)

Edit Profile (accesibil din meniu oriunde în aplicație după Login)

Modulul Ingredientelor și Rețetelor

o Suporta următoarele operațiuni (fiecare are un ecran dedicat):

Listarea ingredientelor utilizatorului (suportă și

operațiuni de ștergere pe fiecare element)

Listarea rețetelor utilizatorului (suportă și operațiuni de

ștergere pe fiecare element)

Figura 31 - Arhitectura PhoneApp

Page 58: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

58

Adăugarea unui nou ingredient (căutare după nume)

Adăugarea unei noi rețete (căutare după ingrediente selectate)

Vizualizarea detaliilor unui ingredient

Vizualizarea detaliilor unei rețete

Aceste doua module interacționează între ele așa cum este descris în Diagrama de Flow

următoare:

Figura 32 - Flow-ul datelor în PhoneApp

Page 59: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

59

4.4.2 Mockup-urile ecranelor

Ecranele aplicației au fost întâi schițate pe hârtie de mana, pentru a descrie cum ar trebui să

arate design-ul grafic. Trebuie menționat că aceste schițe, numite colocvial Mockup-uri, reprezintă

o prima varianta de design, asupra căreia s-a mai intervenit pe parcurs (intervenții minore totuși).

Interesant este că nu am reușit să găsesc o platformă sau o aplicație decenta care să îmi

permită să creez Mockup-uri sau Wireframes pentru WindowsPhone. Aceste Mockup-uri au fost

pozate și incluse în Repository.

Figura 33 - Ecranul de Login

Page 60: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

60

Figura 34 - Ecranele pentru Listare Ingrediente, Listare Reţete si Adăugare Ingrediente

Figura 35 - Ecranele pentru Detalierea Ingredientelor, Înregistrare si Editare Profil

Page 61: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

61

Figura 36 - Ecranul pentru Detalierea Rețetelor

Page 62: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

62

Concluzii și provocări

Așa cum am explicat în detaliu în lucrare, ecosistemul creat demonstrează ușurința cu care

se poate construi o aplicație multi-nivel, de sine stătătoare, fără dependențe fata de resurse externe,

cum ar fi, în cazul nostru, posibila dependenta fata de API-uri comerciale (sau gratuite).

Pe partea de server:

prin cererea unui server manual, controlul complet al implementării revine

dezvoltatorului, astfel asigurându-se constantă în ceea ce privește fiabilitatea şi

stabilitatea sistemului

lipsa dependențelor externe elimină riscul ca proprietarul uneia din dependințe (spre

exemplu un API extern) să decidă retragerea de pe piață a componentelor relevante

pentru noi (situație dezastruoasă în cazul în care întreagă arhitectură a serverului este

construită în jurul unei anumite resurse externe)

abstractizarea implementării codului alături de utilizarea tipurilor de date generice şi a

operațiunilor generice duce la posibilități de expansiune a tipurilor de date suportăte, cu

efort minim

segregarea interfețelor alături de principiul Separation of Concerns duce la cererea unui

cod ușor de urmărit şi ușor de înțeles

Pe partea de proxy (operațiuni intermediare):

încapsularea operațiunilor de comunicare directă cu serverul contribuie din nou la

implementarea principiului Separation of Concerns (în cazul de fată - clientul nu trebuie

să comunice în mod direct cu serverul, altfel orice schimbare pe server necesită şi un

update pe client)

introducerea nivelului intermediar între client şi server elimină dependența directă a

clientului de server, astfel încât serverul însuși se poate schimba complet (altă platformă

de găzduire, altă tehnologie, etc.), fără a afecta în vreun fel clientul (atât timp cât

intermediarul nu schimbă operațiunile expuse către client)

de asemenea, pe lângă eliminarea dependenței directe între client şi server, se adaugă

posibilitatea de a avea clienți multipli pe platforme diferite (intermediarul fiind o

librărie portabilă, se poate converti foarte ușor în orice limbaj - Java / Android sau

Page 63: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

63

ObjectiveC / iOS spre exemplu, pentru a permite construirea unui client pe Android sau

iOS)

Pe partea de client:

am demonstrat cum se poate folosi patternul arhitectural MVVM (esențial pentru

dezvoltarea WindowsPhone şi a aplicațiilor bazate pe Windows Presentation

Foundation în general)

s-a putut observă stilul relativ simplist din punct de vedere grafic al platformei

WindowsPhone, aspect care o diferențiază puternic de Android şi iOS

am explicat în detaliu cum se îmbină în final toate componentele portabile (Modelele

provenite de server, containerul de dependințe pentru Dependency Injection şi Interfață

de Operațiuni a proiectului Proxy)

Adiacent codului în sine, contribuind în mod crucial bunei desfășurări a procesului de

dezvoltare, regăsim platformele de management descrise în detaliu în lucrare:

Team Foundation Server

o subversionarea codului şi organizarea User Stories-urilor în Backlog

o Continuous Integration şi Automatic Deployment

Windows Azure

o serverul şi baza de date SQL

o găzduirea serverului

LucidChart

o creea şi găzduirea diagramelor

NuGet

o cererea şi găzduirea pachetelor comune între aplicații

O mențiune specială revine şi sistemului Google Docs, în care lucrarea de fată a fost

redactată şi verificată, pe secțiuni, înainte ca secțiunile să fie unite în Microsoft Office Word.

Am întâlnit şi o serie provocări interesante, dintre pot enumeră:

probleme în cererea unei definiții de Build cu deployment automat spre Windows Azure

în TFS folosind vNext builds (documentația lasă de dorit când vine vorba de scenariul

acesta în particular) - dificultate mare

Page 64: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

64

probleme cu pachetele NuGet în Build-ul de pe TFS (sistemul de subversionare al TFS

omite uneori să șteargă anumite fișiere, în cazul meu fiind vorba de fișiere rămase în

urmă după update-ul unor pachete NuGet), astfel încât Build-ul eșua, găsind alte fișiere

decât cele la care se aștepta - dificultate medie (sursă problemei nu a fost imediat

evidentă)

limitări ale subscripției gratuite TFS Online şi Windows Azure

o sunt alocate doar 240 de minute de Build lunar (astfel încât a trebuit că unele

checkin-uri să le fac direct, fără Build) - dificultate mică

o între orele 04:00 şi 08:00, TFS şi Windows Azure devin inaccesibile pentru cei

cu subscripții gratuite, fapt care mi-a cauzat probleme uneori (personal tind să

lucrez până târziu în noapte, sau începând foarte devreme dimineaţă) -

dificultate mică

o Publishing Profile-ul folosit pentru deployment automat din TFS spre Windows

Azure mi-a fost suprascris fără să observ, schimbând modul de rulare din

Release în Debug (cauzând probleme cu motorul de rescriere a Code Contracts,

care nu rulează în Debug), necesitând Publish manual - dificultate mică

De asemenea există şi loc de anumite îmbunătățiri:

anumite operațiuni pe baza de date s-ar putea eficientiza (spre exemplu conectarea

rețetelor cu un utilizator s-ar putea face deodată, folosind un Batch Save, așa cum se

procedează la conectarea ingredientelor cu un utilizator) - implementarea ineficientă a

fost făcută intenționat, pentru a exemplifica diferențierea între un Batch Save şi o

operație de salvare iterativă

s-ar putea implementa un sistem de caching al imaginilor pentru rețete şi ingrediente (şi

a datelor de tip text în general) pe telefon (momentan toate datele sunt aduse „proaspete”

la fiecare încărcare de pagină

s-ar putea îmbunătăți în general aspectul aplicației pe telefon şi a paginilor de Debug pe

server (momentan UI-ul e foarte simplist)

s-ar putea adaugă pe server pagini de Debug pentru relaționarea dintre Ingrediente şi

Utilizatori şi pentru relaționarea dintre Reţete şi Utilizatori

s-ar putea introduce un sistem de autentificare pe server pentru paginile de Debug

(momentan sunt accesibile oricui)

Page 65: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

65

s-ar putea implementa un sistem de redimensionare activă a imaginilor în aplicația de

telefon (momentan ele sunt descărcate de pe internet în timp real la dimensiunea lor

nativă, şi afișate într-un container de o anumită dimensiune, în loc să fie redimensionate

direct)

toate imaginile s-ar putea stoca pe server, în loc să fie resurse externe descărcabile

Lista de potențiale îmbunătățiri ar putea continuă (în special în aria securității şi a

optimizării traficului de internet), cele de mai sus fiind cele mai evidente.

În mare, consider că atât lucrarea cât şi aplicația atașată şi-au atins scopul principal (acela

de a demonstra cum sisteme relativ separate pot co-există într-un ecosistem multi-nivel), şi sunt

încrezător că ideea ar putea fi cu ușurință transformată într-un produs comercial. Sunt recunoscător

pentru provocările pe care le-am întâlnit (mi-au oferit ocazia să învăț lucruri noi) şi pentru faptul

că am avut ocazia să lucrez, pentru prima oară, cu Windows Azure (o platformă foarte versatilă şi

ușoară de folosit).

Page 66: FoodApp - Alexandru Ioan Cuza Universityalaiba/pub/absolvire/2016... · 2016-06-19 · o Dorința de a demonstra cum se poate construi un sistem Server - Client folosind cele mai

66

Bibliografie

[1] Microsoft Corporation, Code Contract User Manual - August 14, 2013 -

http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf

[2] Microsoft Corporation, Windows Azure Documentation -

https://azure.microsoft.com/en-us/documentation/

[3] Microsoft Corporation, MSDN - .Net API for Windows Phone -

https://msdn.microsoft.com/en-gb/library/windows/apps/jj207211(v=vs.105).aspx

[4] Microsoft Corporation, MSDN - ASP.NET Web Api - https://msdn.microsoft.com/en-

us/library/hh833994(v=vs.108).aspx

[5] Microsoft Corporation, MSDN - ASP.NET MVC 5 - https://msdn.microsoft.com/en-

us/library/dn448362(v=vs.118).aspx

[6] Microsoft Corporation, Team Services and TFS Documentation -

https://www.visualstudio.com/en-us/docs/overview

[7] Visual Paradigm, Data Flow Diagrams - https://www.visual-

paradigm.com/tutorials/data-flow-diagram-dfd.jsp

[8] Visual Paradigm, Entity Relationship Diagrams - https://www.visual-

paradigm.com/tutorials/erd.jsp

[9] StackOverflow - http://www.stackoverflow.com