Jarda Jirava

Vývojář a architekt řešení postavených na technologii .net framework. Zabývám se jak vývojem webových aplikací za pomoci asp.net, tak také desktopových aplikací winform. Při návrhu řešení a samotném vývoji pak využívám dlouholetých zkušeností se zpracováním obchodní logiky a pravidel aplikací získaných z vývoje komerčních aplikací pro finanční a bankovní instituce.

Microsoft MVP

Microsoft MVP - Client App dev

Silverlight minesweeper

Get Microsoft Silverlight

Navrhi COOL design a vyhraj zkušební let po Evropě!

Poslední příspěvky

.net technology

23
IX

Výzva - doménové objekty a jejich naplnění

Pokračování výzvy z webtrhu pokračuje, tentokráte povídáním o tom, jak jsem si vytvořil doménové objekty pro uchování dat a provedl jejich naplnění.

Doménové objekty

V příspěvku věnovaném definici zdroje dat jsem končil v okamžiku, kdy jsem byl schopen pomocí REST volání získat xml zdroj dat. Z následné diskuze na webtrhu vyplynulo, že Petra zrovna neholduje XSL šablonám a přesto by byla ráda, pokud by si mohla v případě potřeby upravit výsledné HTML, které bude publikovat na web. O tom, jak jsem se tohoto problému zhostil v jednom z příštích článků. Co jsem však potřeboval, bylo mít naplněné objekty, které budou sloužit pro držení dat.

Ze vstupního xml souboru jsem si tak definoval několik elementů, které stojí za to mít uchované, a které se budou moci následně zobrazovat a publikovat na webu. Obdobně bych postupoval i se vstupním xml souborem produktů, zde jsem se tedy zaměřil na knihy. Mnou vytvořené třídy tedy představovaly primitivní POCO (Plain Old CLR Object) objekty s definicí vlastností, které odpovídaly dostupným elementům.

  • Book - ASIN, ISBN, NumberOfPages, PublicationDate, Publisher, Title, Authors, Reviews
  • Author - FullName
  • Review - Source, Content

Linq to Xml

Poté, co jsem měl nadefinovány tyto jednoduché objekty bylo je třeba vytvořit a naplnit daty. K tomu jsem s úspěchem použil nových objektů, které nabízí verze .net frameworku 3.5. A to konkrétně objektů XElement ve spojení s LINQ to XML.

Stažení dat tak bylo otázkou jednoho jediného řádku:

XElement x = XElement.Load(url);

kde proměnná url představovala doplněnou adresu o proměnné parametry, které jsem představil v minulém článku.

Pokud si nyní říkáte, jak složité je naplnit POCO objekty vstupnímy daty a získat tak seznam dostupných knih poskytovaných webovou službou amazonu, je to přesně 23 řádků kódu, z čehož je ještě několik řádků věci vizuálního formátování.

A zde je celé kouzlo, kterým se provede instancování objektů a jejich naplnění

var result = from book in x.Descendants(ns + "Item")
  let attrs = book.Element(ns + "ItemAttributes")
  let revs = book.Element(ns + "EditorialReviews")
  select new Book()
  {
    ASIN = (string)book.Element(ns + "ASIN"),
    ISBN = attrs.Element(ns + "ISBN") != null ? (string)attrs.Element(ns + "ISBN") : string.Empty,
    NumberOfPages = (int?)attrs.Element(ns + "NumberOfPages") ?? 0,
    PublicationDate = (DateTime)attrs.Element(ns + "PublicationDate"),
    Publisher = (string)attrs.Element(ns + "Publisher"),
    Title = (string)attrs.Element(ns + "Title"),
    Authors = new List<Author>(from a in attrs.Elements(ns + "Author")
      select new Author()
      {
        FullName = (string)a
      }),
    Reviews = revs == null ? new List<Review>() : new List<Review>(from r in revs.Descendants(ns + "EditorialReview")
      select new Review()
      {
        Content = (string)r.Element(ns + "Content"),
        Source = (string)r.Element(ns + "Source")
      })
};

Přítelem je let

Teď to možná zní velice divně, ale pokud se blíže podíváte na zdrojový kód uvedený výše zjistíte, že jsem použil magické slůvko let, kterým jsem si vložil do dotazu další proměnné, které používám. První proměnná attrs je pouze pro usnadnění práce, u druhé to také tak může vypadat, ale má to i hlubší význam. Jak se můžete u některých knih přesvědčit, ne všechny obsahují recenzi. Pokud bych poté chtěl naplnit vlastnost Reviews přímo a to odkazem na element EditorialReviews obdržel bych výjimku, konkrétně NullReferenceException, a to se mi zrovna nehodí. Proto jsem si odkaz na tento element uschoval do proměnné a v okamžiku potřeby přirazení do vlastnosti Reviews jej kontroluji a případně vytvořím pouze prázdný generický List<T>.

Scházející elementy

Do obdobné situace jsem se potom dostal v případě, že jsem se snažil naplnit vlastnosti, avšak ve zdrojovém xml scházel požadovaný element. Příkladem budiž třeba scházející ISBN kód nebo nevyplněný počet stránek knihy. V případě ISBN jsem toto vyřešil pomocí ternárního operátoru, v případě počtu stránek jsem potom opět využil možností přetypovat výsledek na nullable type typu int a pomocí operátoru ?? případně vrátit hodnotu 0.

Jak by to vypadalo

Tento krok by se nejspíše odehrál společně s krokem prvním a to při definici zdroje dat. Určili bychom si, které atributy ze vstupního souboru nás budou zajímat, jakým způsobem jsou tyto atributy provázány, stejně tak si řekli, které atributy jsou povinné a které volitelné. Pokud by k vstupnímu xml souboru bylo definováno xsd schéma bylo by to jistě jednodušší.

Časový odhad

Definice doménových objektů a jejich naplnění byl již poměrně rychlý krok. Co bylo spíše nepříjemné je definování vlastností, v čemž jsem s radostí uvítal automatické property. Dalším krokem pak bylo poskládání LINQ dotazu na zdrojové xml. Celkový čas byl odhadem 25 minut + 10 minut testování na vzorku několika stovek záznamů. V případě produktů, které chtěla Petra sledovat by byl čas závislý na tom, kolik atributů by bylo nutné sledovat a mít k nim uložená data.

Publikováno pod: .net technology , výzva
18
IX

Výzva - definice zdroje dat

Jednou z těch obtížnějších překážek na cestě k aplikaci, která ve výsledku vybuduje web z xml exportu bylo najít vhodný zdroj dat.

Jak jsem již v úvodním příspěvku naznačil, Petra se se mnou nespojila a tak její xml export, ze kterého se měl web vytvořit jsem neměl k dispozici. Co bylo řečeno, že dané xml bude obsahovat přibližně 500 produktů s atributy.

AWSE

Když jsem tedy přemýšlel nad tím, jaký zdroj dat použít, vzpoměl jsem si na ukázkový příklad tangerine od Infragistics. Ten pracoval nad veřejnou částí služeb poskytovaných Amazon.com, konkrétně nad AWSE. Po bližším prozkoumání se dá zjistit, že je možné vytvořit si v .net webovou referenci s použitím wsdl a vytvořit si tak proxy na tuto službu.

Úkolem však nebylo takto jednoduše přistupovat k datům, v daném požadavku přeci bylo, že je třeba vytvořit web z xml exportu. A tak jsem našel odkaz na dokumentaci a z ní zjistil, že je možné k webové službě přistupovat i pomocí RESTu (Representational State Transfer) a získat tak výstup v xml.

Poté již stačilo vhodně nakombinovat parametry a vytvořit volání pro získání potřebných zdrojových dat.

Výsledná URL, pomocí níž tedy získávám data o knihách je následující

http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&AWSAccessKeyId={0}&Operation=ItemSearch&Version=2007-07-16&ResponseGroup=Medium&SearchIndex=Books&Keywords={1}&ItemPage={2}

Prvním parametrem, který doplňuji za běhu aplikace je tak AWSAccessKeyId, které je uloženo v konfiguračním souboru aplikace. Tento klíč je přidělen každému, kdo se zaregistruje na stránkách amazon.com pro využívání jejich služeb.

Dále je možné si všimnout, že volám operaci ItemSearch a požaduji zaslání středního výpisu všech dat, což je pro můj vzorový případ dostačující. Dále je uvedeno, jak jsem se již zmínil, že chci získat pouze knihy a to s mnou definovaným klíčovým slovem, což jsem zvolil jako parametr závislý na uživatelově volbě. Posledním parametrem je potom hodnota ItemPage, která získá i další stránky výsledků.

Výhodou tohoto zdroje dat je, že je poměrně obsáhlý, velice dobře zdokumentovaný a přístupný téměř všem, kteří mají touhu projít si se mnou touto výzvou.

Jak by to vypadalo

Zde by se slušelo upozornit, že takto jednoduché by to nejspíše s Petrou nebylo. A i při získání takové zakázky by právě definice dat byla jednou z těch obtížnějších překážek. Právě tento krok by hodně určoval, jak dlouhou dobu bude tento projekt trvat. Také se zde může nejvíce projevit rozdíl mezi začátečníkem, nebo ne příliš zkušeným analytikem.

Časový odhad

Dohledání zdroje dat, nastudování dokumentace a prostudování výstupních xml souborů trvalo přibližně 90 minut. Myslím si, že sezení se zákazníkem typu Petra, který ví co chce a očekává za výsledek, by nemělo zabrat u obdobného projektu více jak 120 minut. Samozřejmě zde hodně záleží na složitosti vstupního xml souboru.

Publikováno pod: .net technology , výzva
16
IX

Výzva z webtrhu

Konec krásného slunečného počasí, které nás provázelo celé léto je správným časem začít se věnovat některým výzvám a předsevzetím, které jsem si dal ještě na jaře.

Právě jednu takovou výzvu jsem si si vzal z webtrhu, kdy se ještě v Březnu ptala Petra, zda by bylo možné vytvořit web na základě xml exportu. Po přečtení jejího požadavku jsem si dovolil skromně podotknout, že na vytvoření jednoduché aplikace bych potřeboval přibližně 5 hodin práce. Což se samozřejmě setkalo s patřičnou odezvou a tak vznikla tato výzva.

Petra od té doby nic nepoptávala a tak jsem si její zadání maličko upravil do potřeb pro sepsání jednoduchého návodu k tomu, jak takovou aplikaci s pomocí .net frameworku ve verzi 3.5 vytvořit. Vzniklo tak několik, na sebe navazujících dílů, které postupně dávají dohromady funkční systém pro vytvoření webu.

Přiznávám hned na začátku, že zadání jsem si zřejmě příliš zjednodušil a je tedy možné, že výsledná aplikace by byla složitější, jako demonstrace toho, že je však možné takovou aplikaci napsat a to velice jednoduše a efektivně, navíc s dodržením potřebného a deklarovaného času je to myslím vhodná ukázka.

Pojďme se tedy podívat na to, o čem budu hovořit:

  • definování zdroje dat jako export pro web
  • definice doménových objektů a jejich naplnění z xml
  • zprovoznění publikačního systému WordPress
  • napojení aplikace na rozhraní publikačního systému
  • vytvoření lokální databáze publikovaných článků
  • šablonový systém pro publikaci článků
  • kompletace jednotlivých modulů do funkčního celku

Články mám v současné chvíli již připraveny a jejich publikace je naplánována na úterý a čtvrtek, proto případně omluvte nedostatky, které se mohou objevit a i to, že v jednotlivých článcích nebudu reagovat na případné připomínky nebo dotazy. V případě potřeby se pokusím vložit nějaký vysvětlující článek.

Publikováno pod: .net technology , výzva
9
IX

WPF a DoEvents

Že aplikace postavené pomocí WPF pracují odlišně od klasických WinForm aplikací snad ví každý, kdo aspoň jednou zkusil vytvořit WPF desktopovou aplikaci.

Proto ani nepřekvapí, že objekt Application ve WPF aplikaci neobsahuje metodu DoEvents, která je známá již od dob Visual Basicu 3 - pokud si tak matně vzpomínám. Nedávno jsem se však dostal do situace, že bych právě takovou metodu, která dovolí aktualizovat UI aplikace potřeboval. Zabezpečení několika po sobě následujících akcí, které se musely odehrát v hlavním threadu aplikace.

Chvíli jsem pátral, jak pomocí objektu Dispatcher zajistit aktualizaci WPF okna a nakonec jsem to našel:

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));

možná to není úplně ideální, ale v danou chvíli mi toto volání postačuje, a snad se bude hodit i vám.

Publikováno pod: .net technology
27
VIII

Certifikace pro .net impulzy pro ano/ne

K napsání tohoto příspěvku jsem se již nějakou dobu odhodlával a stále nevěděl, jak jej začít a uchopit. Názory na certifikace se velice různí a každý si tvoří ten svůj a má vlastní pohled.

Můj pohled na certifikace

V následujících odstavcích se pokusím popsat pouze můj pohled na věc, maličko přiblížit - v rámci možností - systém certifikací pro .net vývojáře, a vyjádřit tak pouze můj názor, se kterým nemusíte souhlasit. Nejdříve uvedu případy, kdy jsem se s otázkou na certifikace setkal a potom přijde třeba ono rozuzlení.

První impulz - setkání .net builder

Právě proč certifikace pro vývojáře a zda mají nějaký význam se řešilo na úvodních setkáních s kolegy z fóra o .netu na builderu. Někdo na tyto zkoušky z dospělosti v .netu měl čas a byl ochoten je složit, jiní v nich neviděli přínos.

Impulz druhý - kontaktní formulář

Jelikož mám složeny zkoušky a jsem tak certifikován jako MCAD - Microsoft Certified Application Developer a zároveň MCPD - Microsoft Certified Profesional Developer, dostal jsem několik otázek skrz kontaktní formulář, zda bych mohl sdělit nějaké podrobnosti k těmto certifikacím.

Impulz třetí - hledá se programátor

Poslední impulz pak přišel tento týden, kdy jsem si přečetl podmínky pro nového programátora. Dovolím si ocitovat jednu větičku:

nepožadujeme nijaké MS certifikace, které ve většině případů stejně o kvalitě nijak nevypovídají

Impulz poslední - ověření svých znalostí

Asi netřeba zmiňovat, ale právě touha po tom ověřit si svoje znalosti vede spoustu lidí k tomu, že se snaží zkoušku pro získání certifikátu složit a doufají, že jim pomůže v jejich profesní kariéře.

Rozuzlení

Když jsem šel na svoji první zkoušku pro získání certifikátu MCP byl jsem nervozní, byť jsem věděl, že mám za sebou dva roky aktivního a intenzivního vývoje na .netu v asp.net, načtenou docela velkou kopu knížek na toto téma, byť ne zrovna ty, které byly doporučovány a nezúčastnil jsem se žádného školení. Pro otestování jsem zvolil školící a certifikační středisko Gopas a cena testu byla přibližně 3 000,- Kč. Moje obavy z nesplnění testu se rychle rozplývaly, neboť jsem zjistil, že to co denně používám je náplní testu, i když několik záludností se také našlo. Přeci jen, pro některé úkony si vytvoříte vlastní vrstvu a pomaličku zapomínáte, jak je to uvnitř řešeno.

Další zkoušky pro získání MCAD potom již probíhaly obdobně, dostatek času a časté používání byly zárukou úspěchu. Pokud bych se měl ještě zmínit o tom, jak probíhaly další zkoušky, asi největší oříšek čekal při testu na získání MCPD, který považuji za velice povedený a dalo by se říci i prokazující nejen znalosti, ale i odolnost vývojáře pracovat pod tlakem.

A reakce na další impulzy? Samozřejmě bude také. Začnu asi u přínosu takového certifikátu pro firmu s vývojářem. Záměrně říkám firmu, protože zde je to, dle mého, markantněji viditelné. Pokud se firma účastní výběrového řízení ve kterém rozhodují manažeři, přeci jen lépe vyznívá, pokud se firma může "pochlubit" tím, že na projektu budou pracovat certifikovaní pracovníci pro danou oblast. Dalo by se to přirovnat k tomu, když firma získá certifikát ISO - čili splnila podmínky. Proto celkem rozumím pochybovačům na potřebnost certifikátu u jednotlivce u kterého přeci jen zadavatel zakázky bude upřednostňovat zkušenosti a předchozí reference.

Čemu však nerozumím a co by mě jako vývojáře odradilo od spolupráce s firmou, pokud se k certifikátům staví obdobně jako ve výše uvedené citaci. Samozřejmě i vývojář, který nemá složenu žádnou certifikaci může být kvalitnějším vývojářem, než ten, kdo touto zkouškou prošel. Neřekl bych však, že složení testu o ničem nevypovídá.

Od vývojáře, který chce zkoušku složit a certifikát získat to znamená minimálně se danou oblast naučit a věnovat tomu čas. Ať už se učí samostatně, nebo čerpá jen ze svých praktických znalostí, vždy je to podloženo znalostmi, které musel někde získat. Někdo může namítnout, že existují společnosti, které se specializují pouze na dané testy a které vás na test připraví, i tak tomu ale musíte věnovat čas a peníze. Vždy to znamená, že musím dané problematice alespoň trošku porozumět.

Certifikát nezaručí návyky a zkušenosti, co však z toho mohu alespoň v současné chvíli vyvodit, že daný vývojář má zájem a chce se danému oboru věnovat, je ochoten podstoupit srovnání s ostatními. A právě už toto považuji za kvalitu daného vývojáře.

Co udělat pro zlepšení vnímání certifikací

Na konci tohoto nadpisu by klidně mohl být i otazník. Opět se na to podívám svýma očima a tím, co jsem si prošel. Jak jsem se již zmínil, líbil se mi test, který jsem absolvoval pro získání certifikátu MCPD. Nejen že trval jednou tak dlouho co předchozí testy, ale obsahoval i více otázek s komplexnějším pohledem. Dle mého vyžadoval více praktických znalostí a zároveň s tím dostával zkoušeného na časového presu a nutnosti se správně rozhodnout. Což si přiznejme, se při vývoji software na zakázku děje poměrně často.

Co bych osobně přivítal a zřejmě by zvýšilo kvalitu certifikovaných vývojářů je skladba odpovědí a větší zapojení zkoušeného do vytvoření odpovědi. Je jasné, že není možné, aby se přímo zapisoval třeba kód programu, ale jistě by bylo realizovatelné mít seznam příkazů a poskládat z nich nejen funkční, ale i optimální kód.

Pokud bych to měl uvést na příkladu:

Mějme následujícím způsobem definovánu sadu příkazů, které můžeme použít ve winform aplikaci. Proměnná cmb definuje ComboBox, který máme naplnit daty. Poskládejte příkazy za sebe tak, aby bylo naplnění comboboxu optimální. Metoda datovyZdroj vrací kolekci objektů v vlastnostmi PropertyName a PropertyValue.

 
   1:  }
   2:  } finally {
   3:  cmb.BeginInvoke();
   4:  cmb.BeginUpdate();
   5:  cmb.DataSource = datovyZdroj();
   6:  cmb.DataBind();
   7:  cmb.DisplayMember = "PropertyName";
   8:  cmb.EndInvoke();
   9:  cmb.EndUpdate();
  10:  cmb.ValueMember = "PropertyValue";
  11:  try {
 

Myslím, že obdobných otázek by mělo být v testech více, zkoušený vývojář by tak byl nucen prokázat své znalosti prověřené praktickým používáním.

Co si o certifikacích myslíte vy a co by pomohlo k jejich lepšímu vnímání?

Publikováno pod: .net technology
10
VII

IQueryable do DataView

Prý nikde není k dispozici popis nebo dokonce kód pro vytvoření DataView z dotazu provedeného pomocí Linq to SQL. Tak jsem se jeden takový pokusil sestavit, byť by si určitě zasloužil ještě nějaké ty úpravy a vylepšení.

DataView ToDataView<T>(this IQueryable<T> query) where T: class

Tak toto je předpis dané extension metody, kterou je možné použít pro vytvoření DataView z dotazu. Celá metoda je velice jednoduchá a jistě ji pochopí každý, alespoń maličko zkušený vývojář. Pro ty ostatní jen malé připomenutí, jak celá metoda pracuje a provádí se převod. Nejdříve však samožná metoda.

using System.Data;
using System.Reflection;
using System.Collections;

public static class DataExtensions {
    public static DataView ToDataView<T>(this IQueryable<T> query) where T: class {
        DataTable dt = new DataTable();
        Type type = typeof(T);
        PropertyInfo[] pis = type.GetProperties();
        foreach (var item in pis) {
            if (!(typeof(ICollection).IsAssignableFrom(item.PropertyType))) {
                DataColumn dc = new DataColumn(item.Name, item.PropertyType);
                dt.Columns.Add(dc);
            }            
        }
        foreach (var item in query) {
            DataRow row = dt.NewRow();
            foreach (var pi in pis) {
                if (!(typeof(ICollection).IsAssignableFrom(pi.PropertyType))) {
                    row[pi.Name] = pi.GetValue(item, null);
                }
            }
            dt.Rows.Add(row);
        }
        return new DataView(dt);
    }
}

Nejdříve je třeba zajistit vytvoření odpovídajících sloupečků. To se provede iterováním přes všechny viditelné vlastnosti třídy s tím, že vynechávám ze seznamu kolekce (EntitySety). Pro jistotu jsem však použil jen rozhraní ICollection, tak aby byly vynechány případné dodatečně definované kolekce.

Následně se již vytvářejí řádky a pomoci Reflection se plní jednotlivé řádky hodnotamy z dotazu.

Posledním krokem je poté již jen samotné vrácení DataView na výstupu z metody.

Publikováno pod: .net technology , code snippet , Linq