Tales from under the Mountain

February 2008 - Posts

MVC framework i sva njegova lica

Na prošlom sastanaku (januarskom) user grupe, prezentova sam jedan deo novog ASP.NET 3.5 Extensions paketa, ASP.NET MVC Framework. Primetio sam da postoje neka pitanja koja su malo opštija od prostih tehničkih činjenica, a na koja nisam stigao da odgovorim jer nismo imali toliko vremena. Jedan blog post bi trebalo sve to da razreši.

Prvo malo osnovnih stvari

Za one koji nisu bili na januarskom sastanku, ili su možda zaboravili o čem use ovde radi, malo podsećanje.

MVC je akronim za Model-View-Controller obrazac (design pattern), koji je svoju kreaciju video još dalekih '70-ih godina u Smalltalk-u. Osnovna odlika ovog obrasca jeste da predstavlja razdvajanje domena u tri jasno razdvojena sloja:

  1. Model, koji služi za prikaz i rad sa podacima, odnosno predstavlja podatke koje koristite u aplikaciji putem objekata.
  2. View, koji služi za predstavljanje informacija krajnjem korisniku.
  3. Kontroler, glavna komponenta predstavlja sponu između modela i view-a i sadrži svu aplikativnu logiku.

Ove tri komponente zajedno imaju . Osnovna razlika između standardnog ASP.NET-a i MVC Framework-a je u tome što zahteve klijenata ne opslužuju strane, već kontrolerli. Drugim rečima, kada klijent uputi zahtev ka web serveru, IIS ne rutira taj zahtev do aspx strane, već do kontrolera. U URL-u kojim klijent zahteva od servera se nalazi nekoliko sučtinskih podataka, kao što je ime kontrolera, ime akcije na kontroleru i parametri koji se prenose. Donji dijagram ilustruje kako ova interakcija izgleda.

image

Dakle, na osnovu gornjeg dijagrama, rečima iskazana interakcija se dešava na sledeći način:

  1. Do kontrolera stiže zahtev, u kome se nalazi informacija koju akciju sa kojim (eventualnim) parametrima je potrebno pozvati. Ukoliko ne postoji podatak o akciji, po default-u se koristi Index akcija.
  2. Kontroler učitava model, ukoliko je potrebno.
  3. Kontroler učitava view, prosleđuje mu podatke ukoliko je potrebno.
  4. Odgovor, odnosno parsiran view, se vraća korisniku.

Primera radi, kontroler izgleda ovako:

image

Dok je view obična aspx strana sa kodom koji se i inače nalazi u običnoj aspx strani:

image

Ovakav rad sa resursima na serveru ima za posledicu nekoliko ključnih razlika između rada sa ovim framework-om i ASP.NET-om. Prvo, ne koristi se postback mehanizam u radu sa stranama. To sa sobom vuče još nekoliko stvari, kao što je recimo da ne postoji ViewState kontrola koje se (eventualno) koriste u view-ovima. Takođe, stranice nisu više ograničene na jedan formular po strani, već ih može imati koliko god se želi. Kada se radi o prenošenju podataka od klijenta ka serveru, u slučaju kada se ti podaci koriste za izmenu podataka u bazi, recimo, ne radi se događajima na strani (kao što je recimo Page_Load), a čuveni IsPostback gubi smisao. U ovom slučaju, u formularu za unos podataka se prosto kao paramtera action atributa odredi akcija na koju bi taj formuar trebalo da se postuje, i onda se u toj akciji radi sa podacima kroz Request kolekciju.

Istini za volju, dosta je lakše ako prosto pokažem neki kod kako to izgleda. Prvo, imamo sledeći HTML kod koji predstavlja formular u koji se unose podaci:

image

I zatim imamo akciju koja menja podatke (naravno, u pitanju je prost primer, tako da simuliam model jednom prostom listom):

image

Ukoliko postoji potreba, može postojati i više formulara po formi i ono što je potrebno jeste uputiti ih na one kontrolere, odnosno akcije koje su pravljene za njih.

Dakle, strane zamenjuju view-ovi, ali se glavna interakcija odvija kroz kontrolere i akcije koje su definisane nad njima. View-ovima se pristupa, odnosno oni se koriste, isključivo putem RenderView metode koja se poziva kroz akcije. Ukoliko je potrebno, view-u se mogu proslediti neki podaci, recimo kolekcija rezultata iz baze podataka ili nešto slično, što bi view trebalo da prikaže konačnom korisniku.

(Napomena: ovo je samo jako kratak i bazičan uvod u MVC Framework, i nisam želeo da zalazim u veće dubine. U kasnijim postovima ću se pozabaviti drugim aspektima MVC Framework-a, ali do tada možete slobodno pogledati postove pod tagom "MVC" na Skot Gatrijevom blogu.)

Zašto?

Osnovno pitanje koje progamerima koji trenutno rade sa ASP.NET-om pada na pamet kada se prvi put susretnu sa MVC načinom rada jeste "zašto"? Kao što sam već naveo, MVC framework ne koristi neke od dobro poznatih stvari kao što su sistem postback-a, pa samim tim i viewstate i još neke stvari. Koje su to onda mogućnosti koje čine da je MVC framework vredan truda i pažnje?

Postoji nekolikoliko razloga kojih mogu da setim:

  1. Lepo formirani URL-ovi. Iako je Janko na istom januarskom sastanku UG-a pokazao kako se može lako napraviti modul za URL rewriting, MVC framework dolazi sa jako moćnim URL routing sistemom, koji je kompletno izmenljiv i ekstenzibilan.
  2. Lakše testiranje koda putem unit testova. Ne samo da su kontroler, model i view odvojeni, i da se samim tim i logika koja se u njima nalazi lakše testira (pogotovo ako pričamo o kontroleru), već je i većina delova implementirana kroz interfejse. Samim tim je lakše praviti tzv. mock objekte i isto tako je moguće raditi unit testiranje bez da se pokreće čitava ASP.NET infrastruktura.
  3. View može da bude aspx strana, kao što je slučaj kada se ASP.NET 3.5 Extensions paket tek instalira, ali može da bude i bilo koji drugi model rada sa podacima koji se šalju korisniku. Trenutno postoji nekoliko različitih templejt jezika u razvoju u okviru MVC Contrib projekta na CodePlex-u.
  4. I ako se ne koristi bilo kakav templejt jezik ili sistem, (X)HTML kod je kompletno pod kontrolom programera.
  5. Svaki korak u izvršavanju može da se presretne, zameni ili da mu se dodaju nove mogućnosti.
  6. Svaki "pokretni" deo mašinerije može da se zameni. Pomenuti MVC Contrib projekat već sada sadrži dosta koda koji može da se koristi ili kao zamena ili kao dodatak na postojeće mogućnosti.

Drugo bitno pitanje je kako bi se ovakav obrazac i sistem uklopio u jednu, recimo, troslojnu arhitekturu. Jedna od prvih stvari koje su me naučili, a mislim da smo i svi naučili, što iz MSDN dokumentacija što iz kurseva, da je pravi način modeliranja aplikativnog sistema troslojna arhitektura, sa jasno određenim slojevima za pristup podacima (data access layer), za poslovnu logiku (business layer ili poslovni sloj) i konačno sloj za prezentaciju (presentation layer ili prezentacioni sloj). MVC obrazac jako podseća na ovu aritekturu, i u manjim aplikacijama, koje ili nisu već tako slojevitno dizajnirane ili takva troslojna arhitektura nije potrebna, on zaista i može da zameni istu. U postojećim aplikacijama ili aplikacijama koje iziskuju troslojnu arhitekturu, MVC obrazac može da pomogne u daljem strukturisanju prezentacionog sloja. Pošto se kao model može koristiti bilo šta, nije teško zamisliti scenario u kome bi model bio skup klasa koji bi se oslanjao na srednji sloj. Ostale dve komponente bi radile identično kao što je već opisano.

ASP.NET Unplugged

Jedna od jako bitnih stvari koju je potrebno shvatiti jeste da MVC framework nije WebForms 4.0, već samo još jedan način da se radi sa ASP.NET aplikacijama. Ukoliko imate potrebu za bilo kojim od faktora navedenih u sekciji "Zašto?", onda će vam MVC framework jako dobro doći. Ukoliko ne, ili ukoliko imate već razrađene sisteme rada sa web formama i standardnim ASP.NET mogućnostima, onda svakako možete da nastavite da koristite ASP.NET na način na koji ste do sada navikli, a koji će biti podržan i dalje.

Ovaj način je samo još jedan izbor koji imate pred sobom.

Skot Hanselman (Scott Hanselman) je okarakterisao MVC framework kao unplugged verziju ASP.NET-a. Neko voli da zaroni jako duboko i da preuzme kontrolu nad svakim aspektom svoje ASP.NET aplikacije; drugi vole jednostavnost i dobru podršku za alate koju im web forms pružaju.

Ultimativno, bitno je da postoji izbor, a na programerima je da izaberu koji model žele da koriste.

 

Peace. Out.

BD.

Posted: Feb 24 2008, 08:08 PM by blackdwarf | with 3 comment(s) |
Filed under: ,
Prve informacije o Silverlight-u 2 (ex. 1.1)

Još jedno kratko "obraćanje javnosti". Skot Gatri (Scot Guthrie) je objavio neke informacije o dolazećoj verziji 2 Silverlight tehnologije. Kao što je naveo Beta 1 se uskoro očekuje, a poreg osnovnih informacija šta je novo, napisao je i 8 članaka koji vas vode kroz kreiranje aplikacije koja pristupa Digg-ovim web servisima.

Zarad kratkog podsećanja, Silverlight 2, nekada nazivan i 1.1, je verzija ove RIA tehnologije koja u sebi donosi mini CLR, odnosno .NET framework, i time omogućava razvoj u .NET jezicima kao što su C# ili VB.NET (i drugi).

Peace. Out.

BD.

Posted: Feb 23 2008, 08:59 PM by blackdwarf | with 1 comment(s) |
Filed under:
Siverlight 1.0 i kontrole

Kratko "obraćanje javnosti". Danas sam naišao na jako koristan blog post Džona Galoveja (John Galloway) o kontrolama u Silverlight-u, odnosno nedostatku istih u verziji 1.0. Iako se planiraju za verziju 2.0 (to je ista verzija koja će sa sobom doneti i mini CLR),  u1.0 verziji ne postoje kontrole kao što su button, select box i sl.

Jedan od načina da napravite ove kontrole je preko JS-a, drugi je preko samog XAML-a,a Džon predstavlja treći način, a to je da koristite već postojeće HTML kontrole koje postavite preko Siverlight sadržaja.

Više o ovoj tehnici možete da pročitate na Džonovom blogu.

Posted: Feb 17 2008, 01:44 AM by blackdwarf | with no comments |
Filed under: ,
Video.Show 1.0 je izašao!

Putem John-a Galloway-a, vidim da je Video.Show stigao do verzije 1.0. Ukratko, to je upakovano rešenje za video hosting koje koristi Silverlight Streaming za skladištenje video fajlova, dok je interfejs urađen u mešavini ASP.NET AJAX-a i Silverlight-a, dok se za data access sloj koristi LINQ-to-SQL

Upakovano rešenje znači da možete da skinete celu arhivu, raspakujete na serveru koji ima .NET Framework 3.5, SQL Server Express i Expression Encoder, modifikujete web.config unošenjem svojih kredencijala za pristup Silverlight Streaming-u i to je to!

 Više informacija možete da vidite i na zvaničnom sajtu kao i u postu.

 Peace. Out.

BD.

VB 9.0 i XML podrška

Kao što je Janko već napisao, u paketu sa ostalim API-jima, u LINQ kolekciji dolazi i LINQ to XML API koji omogućava veoma lak rad sa XML dokumentima. Sa tim novim API-jem ne dolazi samo standardna podrška za upite koji su integrisani u jezik (C#, VB.NET itd.), već i kompletno novi XML API koji donosi različitu koncepciju u radu sa XML podacima. Iako je Janko koristio samo C# u svojim primerima, jasno je da podrška za ovaj novi API postoji i u novoj verziji VB-a, VB-u 9.0.

Postoji, međutim, jedna bitna razlika. Tim koji je radio VB 9.0 je otišao korak dalje, i doveo podršku za XML u ovom jeziku na viši nivo uvođenjem xml literals podrške. Šta to znači?

Uzmimo jedan prost XML fragment, recimo da je mali XML dokument.

<characters>

<character name="James T. Kirk">

<rank>Captain</rank>

<vessel>Enterprise</vessel>

</character>

<character name="Jan-Luc Pickard">

<rank>Captain</rank>

<vessel>Enterprise-G</vessel>

</character>

</characters>

Ukoliko iskopiramo ovaj fragment u Visual Basic kod, i iskoristimo podršku za anonimne tipove, možemo da dobijemo sledeći VB kod:

Dim element = <characters>

<character name="James T. Kirk">

<rank>Captain</rank>

<vessel>Enterprise</vessel>

</character>

<character name="Jan-Luc Pickard">

<rank>Captain</rank>

<vessel>Enterprise-G</vessel>

</character>

</characters>

Od verzije 9.0 Visual Basic jezika, moguće je konstruisati XML dokumente u samom kodu, jer se XML tretira kao "građanin prvog reda". XML je sada tip podatka koji je ravnopravan String ili Int tipu podatka, recimo. Dakle, nije više potrebno koristiti DOM ili klase iz System.Xml namespace-a, moguće je prosto pisati XML unutar samog koda.

Naravno, potrebno je napomenuti još nekoliko sitnica, kao recimo koji je tip element promenljive iz prethodnog primera. Promenljiva element je tipa XElement, koji se nalazi u System.Xml.Linq namespace-u. Korišćenjem anonimnih tipova (koji će možda biti predmet nekog budućeg posta), možemo da izbacimo eksplicitnu deklaraciju promenljive.Naravno, ako želite, možete i da je dodate; rezultat će biti identičan.

Dim element As System.Xml.Linq.XElement

element = <characters>

<character name="James T. Kirk">

<rank>Captain</rank>

<vessel>Enterprise</vessel>

</character>

<character name="Jan-Luc Pickard">

<rank>Captain</rank>

<vessel>Enterprise-G</vessel>

</character>

</characters>

Rad sa XML dokumentima

Naravno, kompletan LINQ to XML API je dostupan u slučaju ovaknog kreiranja XML dokumenata. Nad njima se mogu raditi upiti, mogu se serijalizovati putem metoda iz XElement klase itd. Jankov primer sa dinamičkim generisanjem XML-a putem kombinovanja LINQ-to-SQL i LINQ to XML API-ja je i ovde sasvim moguće izvesti, samo što sintaksa postaje još "čistija" jer možete da koristite XML literals umesto eksplicitnih kreiranja XElement objekata. Recimo:

Dim stdc As StarTrekVBDataContext = New StarTrekVBDataContext("Data Source=zlatkom5;Initial Catalog=AllThingsDemo;Integrated Security=True")

Dim result =    <?xml version="1.0" encoding="utf-8"?>

<characters>

<%= From i In stdc.Characters _

Order By i.Age _

Select _

<character>

<name><%= i.Name %></name>

<age><%= i.Age %></age>

<yearsservice><%= i.Service %></yearsservice>

<allegiance><%= i.Allegiance.Allegiance %></allegiance>

<rank><%= i.Rank %></rank>

</character> %>

</characters>

Naravno, ukoliko želimo da koristimo LINQ to XML da vršimo upite nad već postojećim i kreiranim XML dokumentom, i to je sasvim jednostavno:

Dim result = <?xml version="1.0" encoding="utf-8"?>

<captains>

<%= From c In result...<character> _

Where c.<rank>.Value.Trim() = "Captain" _

Select _

<captain>

<name><%= c.<name>.Value %></name>

<age><%= c.<age>.Value %></age>

<allegiance><%= c.<allegiance>.Value %></allegiance>

<rank><%= c.<rank>.Value %></rank>

</captain> %>

</captains>

Pristup elementima unutar XML dokumenata

Pored podrške za XML kao tip podataka, koja značajno olakšava konstrukciju XML dokumenata, VB 9.0 takođe donosi i XML properties koje značajno olakšavaju pristupanje delovima XML koda po određenim osama:

  • Child osa (child axis) kojom možemo da pristupimo child elementima, npr.: element.<character> će pokupiti sve <characters> elemente iz element objekta.
  • Osa atributa (attribute axis) kojom možemo da pristupimo atributu određenog elementa, npr.: character.@name će uzeti name atribut character elementa.
  • Descendant axis kojom možemo da uzmemo sve "naslednike" (nikada nisam želeo da prevodim ovo, ali neka bude za sada) određenog elementa, bez obzira na to koliko su duboko u hijerarhiji, npr.: character...<rank> (da, to su 3 tačkice)
  • Ekstenziju Value kojom možemo da uzmemo vrednost bilo kog elementa, recimo character.<rank>.Value.

Ukoliko uzmemo jedan fiktivni primer ASP.NET strane za koju želimo da vrati XML dokument kao output (recimo da bismo je iskoristili na jedan REST način), mogli bismo da iskoristimo sve gore navedeno, kao i malo LINQ-to-SQL upita, na sledeći način:

Protected Sub _Default_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

Dim stdc As StarTrekVBDataContext = New StarTrekVBDataContext("Data Source=zlatkom5;Initial Catalog=AllThingsDemo;Integrated Security=True")

Dim query = From c In stdc.Characters _

            Select c.Name, c.Age, c.Service, c.Allegiance, c.Rank

If Request.QueryString("all") IsNot Nothing Then

            query = From a In query _

            Where a.Allegiance.Allegiance = Request.QueryString("all") _

            Select a.Name, a.Age, a.Service, a.Allegiance.Allegiance, a.Rank

End If

Dim result = <?xml version="1.0" encoding="utf-8"?>

<characters>

<%= From i In query.ToList _

Order By i.Age _

Select _

<character>

<name><%= i.Name %></name>

<age><%= i.Age %></age>

<yearsservice><%= i.Service %></yearsservice>

<allegiance><%= i.Allegiance.Allegiance %></allegiance>

<rank><%= i.Rank %></rank>

</character> %>

</characters>

If Request.QueryString("trans") IsNot Nothing Then

result = <?xml version="1.0" encoding="utf-8"?>

<captains>

<%= From c In result...<character> _

Where c.<rank>.Value.Trim() = "Captain" _

Select _

<captain>

<name><%= c.<name>.Value %></name>

<age><%= c.<age>.Value %></age>

<allegiance><%= c.<allegiance>.Value %></allegiance>

<rank><%= c.<rank>.Value %></rank>

</captain> %>

</captains>

End If

Response.Clear()

Response.ContentType = "text/xml"

Response.Output.Write(result.ToString())

Response.Flush()

Response.End()

End Sub

Ova strana će na kraju vratiti običan XML dokument preko HTTP protokola. Jedna od stvari koje je takođe korisno primetiti jeste Response.Output.Write(result.ToString())linija. Ukoliko bismo radili sa starim XmlDocument klasama, ToString() metod na instanci XmlDocument klase bi nam vratio puno kvalifikovano (fully qualified) ime klase. U slučaju novog API-ja, ToString() metod na XElement klasi vraća XML koji je sadržaj te instance, odnosno XML dokument koji smo napravili.

Toliko za ovaj (drugi) post i kratko prebiranje po novoj podršci za XML u Visual Basic-u 9.0. Ne zaborative, VB 9.0 dolazi "u paketu" sa .NET Framework-om 3.5 i Visual Studiom 2008.

Peace. Out.

 BD.

Posted: Feb 11 2008, 05:30 PM by blackdwarf | with 1 comment(s)
Filed under: , ,
ASP.NET Wiki

Za prvi post, jedna kratka vest: juče je otvoren, u beta verziji, ASP.NET Wiki projekat. Njegov tvorac je čuveni Scott Hanselman.

 Wikiju možete da pristupite na http://wiki.asp.net/.

 BD.

Posted: Feb 09 2008, 04:59 PM by blackdwarf | with no comments |
Filed under: