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

6
VIII

ASP.NET vázání dat na zobrazovací prvky

Kdy správně získat data z datového zdroje a data nabindovat na zobrazovací ovládací prvky, to bylo tématem dnešního rozhovoru a já slíbil, že zkusím obhájit své stanovisko.

Zapředl jsem se totiž do rozhovoru s Martinem a to na základě otázky a jeho odpovědí z tohoto příspěvku. Tazatel se ptal, zda existuje funkce na obnovení dat v GridView a přispěvatel se jménem studentik mu odpověděl, nechť použije událost PreRender. Martin poté upozornil, že tato událost není tím správným místem, kde provést dotaz do datového zdroje a nabindovat data. Odkázal přitom na stránku věnovanou tomuto tématu ASP.NET Page life cycle overview, kde jsou popsány jednotlivé události stránky Page.

Já vycházel z mého již dříve napsaného článku o životním cyklu stránky a zkušeností, které mám s tvorbou asp.net aplikací a nemohl jsem s Martinem souhlasit.

Kdy tedy provést navázání dat?

Nemohu souhlasit s tvrzením, že vázat data na zobrazovací prvky by se mělo již v události Init událostního modelu stránky. V tomto kroku jsou inicializovány jednotlivé prvky a rekonstruuje se objektový model stránky. Samozřejmě, pokud nemáme k dispozici ViewState je to pravé místo, pro to jej "nahradit" a získat tak obraz zobrazovaných dat, tak aby se mohli vytvořit všechny potřebné zobrazovací prvky i s jejich, na klienta, odesílanými údaji.

Posléze, v následujícím zpracování životního cyklu stránky, dojde k načtení dat z ViewState - v případě jeho vypnutí simulujeme napojením dat - a následně k nastavení hodnot formulářových prvků hodnotami z předané kolekce Forms.

Život stránky jde dál a následuje událost Load stránky, kdy se většinou provádí test na vlastnost IsPostBack a případné nahrání a navázání dat. Začátečnickou chybou tak je, že nedojde k otestování zda došlo k postbacku a tak si vývojář přepíše získaná data jejich původní hodnotou a nadělá si spoustu problémů, které neví jak řešit. I proto se mi jeví navázání dat v tomto okamžiku jako nevhodné a vlastně se tím nic nezíská.

A to i vzhledem k tomu, že následuje vyvolání a zpracování změnových např. textchanged a postback událostí - pro prvky implementujících rozhraní IPostBackEventHandler. Kde se snažíme o uložení dat zaslaných klientem do naší aplikace a zároveň můžeme na základě jeho rozhodnutí provádět další operace s naší aplikací. Tyto operace pak mohou vést k tomu, že zdroj dat bude jiný nebo bude obsahovat jiné hodnoty, které v okamžiku zpracování předchozích události ještě nevíme - nebyli jsme o nich informováni, samozřejmě si je můžeme zjistit již dříve, například přímým dotazem na hodnotu do kolekce Forms.

Získání dat a jejich navázání

A právě po proběhnutí výše uvedených akcí je myslím nejvhodnější doba, kdy získat nová data a provést jejich navázání na zobrazovací prvky. Pro verze asp.net 1.x je tedy možné využít události PreRender,pro asp.net 2.0, kde byl událostní model rozšířen, je to událost LoadComplete - samozřejmě je též možné využít PreRender událost.

Určitě se ptáte, jaké k tomu mám podklady, že doporučuji zrovna tyto události. Na prvním místě jsou to osobní zkušenosti, které jen těžko něco může nahradit. Již zmíněné chování, kdy dochází k postupnému "uvědomování si" co vlastně uživatel chce zobrazit až třeba po implementaci asynchronního volání ve verzi asp.net 2.0. Kde je možné si zaregistrovat počáteční a koncový handler v metodě AddOnPreRenderCompleteAsync a kdy ke zpracování asynchronního volání dojde v okamžiku mezi voláním metod OnPreRender a OnPreRenderComplete - tedy taktéž je využito tohoto okamžiku, abychom výsledek zdlouhavé operace navázali na zobrazovací prvek ve stránce.

Samozřejmě budu rád, pokud se mnou nebudete souhlasit a opravíte mě, já se alespoň poučím. Uvítám však i opačný názor, že nejsem sám, kdo k tomuto řešení dospěl.

Publikováno pod: .net technology , builder.cz
3
VIII

.net aplikace proti mysql databazi

Dostal jsem se k možnosti vytvořit jednoduchou aplikaci, která se bude starat o import dat do mysql databáze. Říkal jsem si, že by to neměl být velký problém, podobných můstků jsem již několik vytvořil a tak jsem se do toho pustil.

Jelikož jsem měl již dřívější zkušenosti s mysql tak mi bylo jasné, že cesta přes ODBC určitě nepovede, protože je ve verzi 3.51 stále ještě chyba při ukládání datových typů (a možná to není jediná chyba) a vyšší verzi jsem nenašel.

Na stránkách mysql je k dispozici connector pro připojení k mysql databázi a tak jsem jej hodlal vyzkoušet. Aplikace pro import byla napsána poměrně rychle, a tak nastal čas testování.

Připojení a dotazy do mysql

A právě fáze testování přinesla, pro účely aplikace, nelichotivé výsledky. Aktualizace probíhala pomocí volání metody ExecuteNonQuery() na vytvořené instanci třídy MySqlCommand s naplněnými parametry. Čas potřebný k vykonání jednoho dotazu, sestávajícího pouze z volání dané metody, byl v rozmezí 60-80ms. Což představovalo v podání profileru nějakých 98% celkového času práce aplikace. Po vynásobení množstvím záznamů jsem se dostal k neúnosným číslům.

Alternativy v připojení nebo změna aplikace?

Začal jsem tedy hledat alternativy v připojení k mysql databázi. Vyzkoušel jsem ještě jeden provider, který měl však velice podobné časové nároky a tak nezbývalo, než zkusit změnit chování samotné aplikace. První varianta, která mě napadla je, celé to přesunout do samostatných vláken, což jsem ale záhy zamítl. Nechtěl jsem začít spravovat jednotlivá vlákna a ani ThreadPool jsem v tomto scénáři nechtěl použít - spíše šlo o jistou intuici a třeba jsem to měl zkusit.

Obdobně dopadl, tentokát již vyzkoušený pokus s voláním asynchronních metod, které jsou ve verzi ADO.NET 2.0 podporovány. I tak však vykonání několika stovek až tisíců příkazů bylo časově neúnosné. A tak jsem zkusil poslední možnost, která mě napadla.

Naplnil jsem vstupnímy daty DataTable a tu jsem pomocí vytvořeného DataAdapteru naimportoval do databáze. Výkon sice nebyl oslňující, ale přeci jen citelně lepší než v předchozích dvou případech. Navíc se v tomto scénáři dalo velice dobře využít výhod ThreadPoolu a to pro každou importovanou DataTable.

Víte o něčem lepším?

Je klidně možné, že existuje ještě lepší řešení, nebo i rychlejší connector pro přístup k mysql databázi. Pokud se chcete podělit, vaše rady určitě přivítám.

Publikováno pod: .net technology
30
VII

Another day, another asp.net web system

Už je to tak, nastal nový den a s ním i loučení se starým community serverem. Nebylo to špatné, ale chtěl jsem něco víc. Navíc moje touha po novém poznání přerostla v potřebu si vše vyzkoušet na vlastní kůži.

A tak vznikl .net web system, který pohání tento blog nejen o .netu, ale také úvodní stránku, stejně jako stránky s fotografiemi a soubory ke stažení.

Ze zákulisí

Chtěl bych se podělit o postřehy ze zákulisí takového vývoje, které jsou určitě zajímavé a každý je rád slyší nebo čte. Je to už nějaký ten pátek, co jsem se začal porozhlížet po něčem novém, kam se posunout a jakým směrem obohatit svoje znalosti. Docela mi v rozhledu pomohl tým kolem patterns & practices, který v té době vydával nové a zlepšené verze software factories pro kde co.

Právě tam se nejspíše urodila myšlenka toho, že opustím community server a zkusím si napsat něco svého, co nemusí pohánět jenom tento blog, ale třeba použiji i jinde, na komerčních projektech - pokud víte o někom, kdo by spolupráci uvítal, určitě mi dejte vědět.

Co bylo důležité dodržet, je stejné chování pro okolí, jaké měl již zmíněny community server. Ovšem jen navenek, uvnitř jsem chtěl větší volnost a modularitu. A tak jak jsem se jal studovat a prokousával se novými informacemi, zjišťoval jsem, jak jde vše řešit ještě více jednoduše a elegantněji.

V té době jsem měl navíc za sebou již několik sezení s Petrem, kterému jsem vysvětloval principy fungování .net frameworku a s tím spojené výhody a také nástrahy tvorby asp.net aplikací. Petr následně z těchto rad a zapojením své invence stvořil web pro pomoc ostatním. A já tak měl možnost srovnání, na straně jedné, ten klasický, již dobře známý princip tvorby asp.net aplikace, událostního modelu stránky, web controlů a všech těch vychytávek, které si pro nás pánové z MS přichystali a poznáním, že existuje pro dané účely jiná možnost jak aplikaci pod .net napsat a přitom si zachovat možnost využít výhod .netu.

Proč ta tajemnost?

Určitě si říkáte, proč jsem opět tak tajemný, podobně jako třeba v minulém příspěvku, a neřeknu jak jsem tenhle systém navrhnul a napsal? Tentokrát je to z mé strany záměrné a hnedka prozradím proč. Rozhodl jsem se totiž jednoho z aktivních čtenářů odměnit. A když už říkám aktivního, tak to znamená, že od vás budu nejspíše něco také chtít. Tak trochu to mohou být znalosti, ale třeba jenom náhoda při procházení tohoto blogu, kdo ví, nechám to jen na vás.  Mnou napsaný .net web systém je postaven na několika zajímavých projektech, které mi usnadnily spoustu práce a nabídly volnost a snadnou konfigurovatelnost a rozšiřitelnost. Na vás je, odhalit co nejvíce, alespoň však čtyři projekty a napsat mi do komentářů jejich názvy - jako malou nápovědu přidám, že někteří, kdo mě znají více mohou být maličko překvapeni. A co za to? Doma mám ještě zabalenou krabici se hrou Age of Empires III a tu rád osobně předám jeho výherci tady v Praze, případně zašlu i do nejzazšího místa této malé, ale naší, země.

Takže neváhejte, doufám, že cena je lákavá a brzy se budu moci podělit o více zážitků jak jsem tento web systéme navrhnul a nakonec implementoval a také otestoval. A vlastně to nebude jenom o web systému, ale také o těch projektech.

A ještě jedna nápověda závěrem, pro generování obsahu do Vaší oblíbené RSS čtečky, ze které jste sem nejspíše zavítali, jsem použil projekt RSS.NET.

PS: a pro ty, kteří mi chtějí jen popřát ke kulatému výročí, jsou komentáře samozřejmě také otevřeny :-)

Publikováno pod: .net technology
15
VII

Když se nevlezete do škatulky

přijde vám to v první chvíli docela líto. Vzápětí si však uvědomíte, že je to něco, co vás odlišuje od ostatních, že jste něčím výjimeční a že takovým vlastně chcete být. A něco takového jsem si mohl uvědomit i já na začátku tohoto měsíce.

Při té příležitosti si vzpomínám na dobu před více jak půl rokem, kdy jsem v Microsoftu seděl u kulatého stolu, kam jsem byl přizván, ještě s dalšími diskutujícími a celým tím blokem se vynula otázka: "Jak přilákat více vývojářů k .net frameworku?" Já se v té době, a i poté, již šestým rokem snažil přispět svojí troškou tím, že jsem odpovídal a pomáhal na serveru builder.cz ve fóru o .netu. Převážně začátečníkům, kteří se rozhodují zda u .netu zůstanou, ale i těm pokročilejším. A že těch otázek i odpovědí není málo, vždyť si jistě samy vzpomenete nejen na své začátky, kolik jste měli otázek - i já ještě zjišťuji, že jich je přede mnou spousta nezodpovězených.

Jednou z nich je, po začátku měsíce, i další. "Mám se raději zaškatulkovat a nepomoci tak, v konkrétním případě, asi 60% dotazujících se?" Vždyť .net framework je komplexní a pokrývající široké spektrum možností vývoje software a to od asp.net webových aplikací, přes winform desktopové aplikace, webové služby a ... takhle bych ještě chvilku mohl pokračovat. Každý začátečník má pak svůj cíl a cestu, kterou se chce vydat. Moje rozhodnutí je tedy celkem jasné, raději budu mít dobrý pocit z toho, že pomohu a ostatním ukážu .net framework z pohledu, který znám, i to že se dá .netem dobře bavit a vytvářet různorodé aplikace a vlastně nejen to, byť zřejmě přijdu o nějaké ty výhody.

Teď se určitě všichni ptáte - nejspíše skutečně všichni, až na jednoho, proč tohle vlastně píšu? Je to tak trošku proto, abych vyjádřil odeznělé pocity ze zklamání, a třeba za půl roku, za rok se dočtete a dozvíte víc. Ale spíše ne, protože se jen nerad škatulkuju.

Všem pak přeji krásné prázdniny a dovolené a zůstaňte výjimeční. :-)

12
VI

Lepší je se ptát

než odpovídat, potom to alespoň nevypadá jako, že jste blbec, když neznáte odpověď. Mimochodem, to mi lehce připomělo báječnou hru Blbec k večeři v nastudování divadla Bez zábradlí.

Ale zpátky k tomu, o čem jsem se chtěl rozepsat. Jak jistě víte, již dlouhou dobu jsem členem komunity kolem serveru builder.cz a jeho fóra o .net. Nedávno jsem dokonce uspořádal i první neformální setkání přispěvatelů tohoto fórá, ale to už opět odcházím od tématu.

Proč je tedy lepší se ptát? Nejste totiž limitováni ničím, nejspíše řešíte problém, který zrovna pálí vás a nikoho jiného a v hlavě máte nějakou ideu. Tuto ideu se potom snažíte s větším či menším úspěchem přetransformovat v otázku a pak už jenom čekáte a říkáte si: Milé fórum, poper se s tím jak umíš. Samozřejmě je tu i druhá strana, kdy se ptáte, protože se snažíte někoho zkoušet a odpověď už dávno znáte, ale to není zrovna náš případ.

Ač nemám zrovinka rád různá přirovnání, k některým otázkám z poslední doby bych jedno takové, lehce kulhající, měl. Otázka vypadá asi následovně.

Mám dvě kola, řídítka, nějaký morot a kousek drátu se špagátem. Milé fórum, slyšel jsem, že z toho udělám auto. Bude mi stačit francouzský klíč nebo mám použít hever?

Ne ne, tohle není problém jenom u otázek, týkajících se .netu, ono se stačí podívat i do ostatních diskuzí a přijdete na ještě větší perly. O těch zase někdy příště.

Jak se také zeptat?

Některé určitě napadne otázka, jak je tedy lepší se zeptat, co je na takové otázce špatně a jak ji zlepšit. Vždyť co, vyjmenoval jsem snad vše, co bylo možné a co vím a znám.

Co mi však na takové otázce schází, možná jenom mě, je cíl, dílčí nebo konečný výsledek, našeho snažení. Tazatel vesměs všechno má, jenom neví jak to dát dohromady. Nezabývá se již otázkou, zda mu něco neschází, zda je možné se takto k výsledku dobrat, řeší už jenom konkrétní způsob a pokud možno konkrétní implementaci.

Odpovídající na straně druhé chvíli přemýšlí a snaží se podané informace napasovat někam do svých současných znalostí, takříkajíc čte mezi řádky ta nevyřčená slova a hledá za nimi hlubší smysl a význam takového snažení a nutnosti položit takto koncipovanou otázku, jenže ve většíně případů je o pověstný chlup vedle. Potom si připadá skutečně jak ten blbec.

8
V

Názor k použití objektů podle Ronnieho

Minulý týden jsem si přečetl příspěvek Ronnieho "Proč používat objekty - pokračování" a nedalo mi to, abych nereagoval v komentářích. Přeci jen mám trochu jiný pohled na danou problematiku vycházející z mých zkušenosti a dosavadních znalostí.

Pod článkem se rozjela fajn debata, ze které jsem poznal pohled i jiných vývojářů na používání objektů. Pokud jsem správně pochopil jejich výroky, nelíbí se jim možnost používat protected viditelnost u objektů. Konzistence a zapouzdření je pro objekty požadováno, avšak můj názor je takový, že tyto požadavky nejsou porušeny tím, že objekt zpřístupní svůj rozšířený interface svým potomkům. Znamená to, že objekt má vesměs dva (v případě .net tři) přístupné interface.

Public interface

První interface je tvořen public viditelností vlastností a metod. Tento interface je přístupný všem okolním objektům, které chtějí s naší instancí třídy komunikovat.

Rozšířený interface za pomoci protected viditelnosti

Public interface však není jediný, který může architekt zpřístupnit. Dalším a neméně důležitým je i tento interface - byť se to někomu nemusí zdát. Samozřejmě v tomto případě hodně záleží na samotném tvůrci, aby zajistil, že tento interface neporuší konzistenci objektu. To znamená, zpřístupnil pouze takový interface, který konzistenci neporuší. Nemusí se však jednat o public interface, ale pouze takový, který uvidí třídní potomci. V .net frameworku, a vesměs asi v každém propracovaném a dobře navrženém frameworku, nalezneme spoustu tříd, který zpřístupňují svůj rozšířený interface svým potomkům.

K čemu rozšířený interface použít

Napadá mě hned několik možností, při kterých návrhář třídy bude využívat tohoto rozšířeného interface k zajištění konzistence a přitom nedojde k porušení zapouzdření. Pro lepší názornost bude vhodnější uvést příklad takové třídy a jejího potomka.

Dejme tomu, že máme třídu Osoba, která má několik vlastností (atributů) a metod pro manipulaci s touto třídou. Jednou z veřejných metod je i metoda pro uložení objektu, tato metoda by měla zkontrolovat, zda je při splnění komplexnějších podmínek umožněno uložit objekt Osoba. Tyto podmínky platí i pro potomky.

V případě, že bych Osoba poskytovala pouze veřejný interface, musel by každý potomek zajistit kontrolu těchto podmínek, neboť ukládání je pro každého potomka malinko odlišné. Jak si ale v takovém případě může být autor třídy Osoba v tomto jistý? Řešení je v tomto případě zajištěno implementací návrhového vzoru Template method a tedy rozšířením interface pomocí protected metody. V takovém případě nebudeme public metodu k uložení označovat jako virtuální a po zkontrolování podmínek budeme volat protected metodu.

Taková třída tedy může vypadat následovně:

public abstract class Osoba {
public void Save() {
  if (podminkySplneny()) {
    saveInternal();
  } else {
    // zalogování informací a případné vyvolání výjimky
  }
}
protected abstract void saveInternal();
}

Tímto způsobem máme zajištěno, že objekt zůstane zapouzdřený a viditelný zůstane pouze požadovaný veřejný interface, neboť je celkem oprávněný požadavek, aby okolí nemohlo volat žádost o uložení objektu, bez kontroly splnění podmínek.

Je to jen jeden z mnoha případů, proč si myslím, že není nebezpečné používat také protected viditelnost u objektů. Ale jak jsem se již někde vyjadřoval, vše je to o konkrétním člověku. Pokud navrhnu veřejný interface špatně, může to být více nebezpečné než pokud správně navrhnu celou třídu i s rozšířeným interfacem.

Samozřejmě je to jen můj pohled na danou problematiku a nemusí to být ten nejlepší pohled, vychází však z mých současných znalostí a zkušeností. Určitě se nebudu bránit jakékoli konzultaci nebo připomínkám, neboť jenom tak je možné si utřídit poznatky a porovnat je s okolím.