<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:georss="http://www.georss.org/georss" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-25517922</id><updated>2009-06-12T23:30:40.735+02:00</updated><title type="text">Ali Baba programuje</title><subtitle type="html">Programátor Ali Baba udílí rady do života.</subtitle><link rel="alternate" type="text/html" href="http://www.kolman.cz/alibaba/default.htm" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.kolman.cz/alibaba/atom.xml" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/AliBabaProgramuje" /><feedburner:info uri="alibabaprogramuje" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry><id>tag:blogger.com,1999:blog-25517922.post-3228661414923382495</id><published>2009-03-16T18:49:00.049+01:00</published><updated>2009-03-23T16:42:53.718+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DSL Tools" /><title type="text">Trochu teorie kolem DSL</title><content type="html">Doufám, že vás v mém posledním postu moc nevystrašilo slovní spojení "Domain-Specific Language". Je to jen další buzzword: zní to sofistikovaně, ale ve skutečnosti to není nic nového. Laskavý čtenář, kterému rostou víc vousy než vlasy, si možná vzpomene na &lt;a href="http://catb.org/~esr/writings/taoup/html/minilanguageschapter.html"&gt;minijazyky v unixu&lt;/a&gt;, což není nic jiného než DSL - malý jazyk vymyšlený pro konkrétní účel.&lt;br /&gt;&lt;br /&gt;Dnes se DSL nejčastěji objevují ve formě konfiguračních souborů. Například *.hbm.xml soubory v NHibernate jsou zapsány jazykem speciálně vytvořeným pro problémovou oblast (=doménu), kterou je v tomto případě mapování mezi databází a objekty. Nebo obyčejný web.config v asp.net aplikaci: To je jazyk specifický pro konfiguraci .NET website, kde je nutné určit které moduly a handlery budou pro který typ souboru použity:-) Takže s nějakým DSL se setkal každý programátor, jen o tom možná neuvažoval jako o DSL.&lt;br /&gt;&lt;br /&gt;Doporučuju vám &lt;a href="http://www.infoq.com/presentations/domain-specific-languages"&gt;tuto prezentaci&lt;/a&gt;, kde Martin Fowler vysvětluje, co si představuje pod pojmem DSL. Všimněte si, že říká že hranice co už je DSL a co ještě není je neostrá. Dokonce i C# nebo java kód může být chápán jako DSL, kde forma zápisu je shodná s programovacím prostředím. V takovém případě se jedná o &lt;i&gt;interní&lt;/i&gt; DSL, který lze přímo spustit.&lt;br /&gt;&lt;br /&gt;Oproti tomu &lt;i&gt;externí&lt;/i&gt; DSL jazyky mají svůj vlastní způsob zápisu, nezávislý na existujících programovacích jazycích. To přináší větší svobodu v definici syntaxe jazyka, na druhou stranu musíme kód nějak parsovat a interpretovat sami. To je natolik složité, že ve většině případů by komplexita parseru a generátoru převážila nad zisky z používání DSL jazyka, což je mimochodem důvod, proč mají tvůrci dnešních DSL tak rádi XML, XSD a XSLT. Další nemalé úsilí by bylo zapotřebí k tomu, aby se "user experience" při používání DSL jazyka přiblížila moderním IDE: Kdo jednou zkusil intellisense ve Visual Studiu a průběžnou analýzu kódu s ReSharperem, těžko se bude chtít vracet k plaintextu. &lt;br /&gt;&lt;br /&gt;Když už máme náš nový jazyk definovaný a umíme ho parsovat, je nutné se rozhodnout jak ho budeme interpretovat. Můžeme z DSL jazyka generovat zdrojové kódy v jiných (existujících) jazycích, kompilovat je a distribuovat náš program jako binární knihovny. Druhou variantou je napsat "framework", který bude náš DSL kód interpretovat za běhu a distribuovat tento framework s výchozí podobou DSL kódů, které si koncový klient může upravit podle svého. Typickým příkladem prvního přístupu jsou programy pro modelování v UML, v druhém případě pak konfigurační soubory nebo skriptovací jazyky. &lt;br /&gt;&lt;br /&gt;Generování kódu nám jako autorům programu dává do rukou mocnou techniku: Možnost následných úprav vygenerovaného kódu v místě různých "extension points", jako jsou partial třídy nebo double-derived pattern (vygenerujeme base třídu s virtuálními metodami a vlastnostmi a prázdného partial potomka). Díky tomu náš DSL jazyk nemusí řešit všechny krajní varianty. Když to obrátíme můžeme říct, že pokud se rozhodnete váš DSL interpretovat až za běhu, musíte vaše řešení zcela popsat pomocí DSL - včetně všech výjimek a minoritních úkazů. Dostáváte se tak do "customizační pasti", kdy musíte napsat kompletní framework dřív, než budete moci váš DSL použít. Generovat kód je jednodušší, protože se stačí zaměřit na bežné jevy a speciální případy ošetřit v C# nebo jiném vhodném jazyce. Postupně můžeme přidávat počet situací, které jsou v našem DSL řešeny, nebo dokonce můžeme časem implementovat framework pro interpretaci za běhu, ale nebrání nám to začít v malém.&lt;br /&gt;&lt;br /&gt;A nyní, milé děti, můžeme plně ocenit sílu language workbenches jako je DSL Tools pro Visual Studio: Jsou to externí jazyky, kde máme syntaxi plně pod kontrolou, máme k disposici parser a generátor, prvotřídní integraci do vývojového prostředí, a navíc grafický editor s předpřipraveným systémem validace modelu, který můžeme upravovat dle libosti. Programátorský Eden. Jediné co chybí je standardní způsob slučování více modelů do jednoho, ale to lze poměrně jednoduše obejít. O tom ale jindy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-3228661414923382495?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/WNDK95-R1Iw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/3228661414923382495/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=3228661414923382495&amp;isPopup=true" title="Počet komentářů: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/3228661414923382495" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/3228661414923382495" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/WNDK95-R1Iw/trochu-teorie-kolem-dsl.html" title="Trochu teorie kolem DSL" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2009/03/trochu-teorie-kolem-dsl.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-5335360842495540809</id><published>2009-03-14T23:26:00.020+01:00</published><updated>2009-03-25T11:39:37.357+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DSL Tools" /><title type="text">Model Driven Development v praxi</title><content type="html">&lt;i&gt;&lt;a href="#screencast"&gt;Přeskočit přímo na video&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Kolem modelování v software už byla napsána a řečena spousta vznešených slov (&lt;a href="http://www.omg.org/mda/images/mda_text.gif"&gt;třeba zde&lt;/a&gt;). Podívejme se proto na jednoduchý způsob, jak ho implementovat v praxi.&lt;br /&gt;&lt;h3&gt;Příklad&lt;/h3&gt;&lt;br /&gt;Máme webovou aplikaci (např. online shop), která ukládá data do databáze. Aplikační logika je implementována jako &lt;a href="http://martinfowler.com/eaaCatalog/domainModel.html"&gt;domain model&lt;/a&gt;, takže pro každou "entitu" v reálném světě (klient, produkt, objednávka atd.) existuje v aplikační vrstvě třída. Objekty jsou do databáze mapovány pomocí NHibernate.&lt;br /&gt;&lt;br /&gt;A nyní si představte, že do objednávky budete chtít přidat další údaj, kontaktní telefon. Maximální počet znaků je 9. Musíte editovat webovou stránku s formulářem objednávky, musíte přidat javascriptový validátor, přidat property &lt;span class="code"&gt;Phone&lt;/span&gt; do třídy &lt;span class="code"&gt;Order&lt;/span&gt; a rozšířit její validační metodu, do mapovacího souboru Order.hbm.xml doplnit &lt;span class="code"&gt;&amp;lt;property name="Phone" type="string" length="9" not-null="true" /&amp;gt;&lt;/span&gt; a do databázové tabulky &lt;span class="code"&gt;tblOrder&lt;/span&gt; přidat sloupec &lt;span class="code"&gt;Phone NVARCHAR(20) NOT NULL&lt;/span&gt;. Dost práce, navíc spousta duplicity, že? A po týdnu zjistíte, že telefon se do 9-ti znaků nevejde (národní předvolby) a rozhodnete se zvětšit délku údaje na 20 znaků. Budete opět muset upravit všechna zmíněná místa, na žádné nezapomenout a neudělat překlep.&lt;br /&gt;&lt;h3&gt;Model&lt;/h3&gt;&lt;br /&gt;Přitom se stále jedná o jeden logický koncept: Objednávka má pole telefon s délkou 20 znaků. Daleko rozumnější by proto bylo udržovat tyto definice na jednom místě ("model" naší aplikace) a ostatní "artefakty" (části kódu) generovat automaticky. Vymyslíme tedy způsob zápisu, jak model definovat, vytvoříme model naší aplikace a pak ho budeme nějak parsovat a podle nějakých šablon generovat artefakty kódu. Způsob zápisu modelu je náš &lt;b&gt;doménově-specifický jazyk (DSL)&lt;/b&gt;, který umožňuje zachycovat entity z domain modelu aplikace.&lt;br /&gt;&lt;br /&gt;Nabízí se tři řešení, jak to udělat: Vlastní implementace, univerzální CASE nástroj, nebo použít existující "&lt;a href="http://martinfowler.com/articles/languageWorkbench.html"&gt;language workbench&lt;/a&gt;".&lt;br /&gt;&lt;br /&gt;Vlastní implementace vypadá jednoduše: Uděláme nějaký "texťák" (céčkař) nebo "iks-em-elko" (dotneťák) a napíšeme si jednoduchou utilitku, která ho přečte a na stanovená místa vyplivne kód, v lepším případě pomocí nějakých šablon (např. XSLT). Jenže model bude mít velmi mnoho vlastností a mezi prvky modelu budou vztahy které nelze definovat jinak než pomocí nějakých "ídéček". Ze začátku jednoduché jak facka, ale až model naroste, bude velmi nepřehledný a udržovat ho bude dost pracné. Takže se uchýlíte k tomu, že ve svém volném čase budete psát další utilitky pro kontrolu modelu, prohlížení modelu s navigací po vztazích mezi entitami, editor se zvýrazňováním syntaxe atd. To vám zabírá čas který by jste měli věnovat učení se novým technologiím. Výsledek nestojí za to, veřte mi, zkusil jsem to:-) Navíc ztrácíte podporu internetové komunity, čímž se okrádáte o nejrychlejší způsob řešení problémů - gůglení.&lt;br /&gt;&lt;br /&gt;Velmi svůdné řešení je použít nějaký CASE nástroj, nejspíš na bázi UML. Jejich nevýhoda ale je, že jsou příliš univerzální, takže 90% jejich fíčur vůbec nepoužijete, a naopak když budete potřebovat něco trochu jiného než program umožňuje, budete vymýšlet nejrůznější hacky jak to udělat, což opět znepřehledňuje model. Výsledkem je velmi vratký rovnák na vohejbák (věřte mi, také jsem se o to pokoušel). Dále se připravte na to, že tyto nástroje mají obvykle strmou učící křivku (zná někdo lepší překlad "steep learning curve"?), že budete muset zjistit jak to integrovat s vaším IDE a že každý vývojář bude potřebovat placenou kopii nástroje.&lt;br /&gt;&lt;br /&gt;"Language workbench" je Fowlerův termín pro sadu nástrojů, které usnadňují tvorbu vlastních DSL jazyků. Plurál je na místě, pro každý účel můžete vytvořit speciální jazyk přesně na míru problému, daleko vhodnější než různě přiohnuté UML. Tyto nástroje zahrnují tvorbu jazyka, práci s modelem, generování artefaktů z modelu a integrace do IDE. Je to nejlepší z obou světů: Snadno vytvoříme jazyk přímo pro konkrétní účel včetně generování artefaktů, a přitom máme k disposici nástroje a internetovou komunitu. Navíc můžeme jazyk tvořit inkrementálně, začít skromě a postupně přidávat funkčnost podle potřeby, tam kde se ukáže že je to možné a přínosné. Tak si v našem příkladě můžeme vytvořit doménový jazyk pro definici entit a jejich vlastností, a později přidat "constraints", např. minimální a maximální hodnoty vlastnosti, a upravit šablony aby generovaly validační kód na všechny vrstvy kde je potřeba.&lt;br /&gt;&lt;br /&gt;Osobně vím o dvou takových "workbenchích", jedna je &lt;a href="http://www.jetbrains.com/mps/"&gt;Meta Programming System&lt;/a&gt; od JetBrains (stále ještě v beta), druhá &lt;a href="http://msdn.microsoft.com/en-us/library/bb126235.aspx"&gt;DSL Tools&lt;/a&gt; od Microsoftu, součást Visual Studio SDK. První jsem nezkusil, ale pokud programujete v javě a používáte IDEA, asi by to stálo za pokus. Druhou používáme v praxi pro definování aplikačního domain modelu a generování SQL, HBM, domain tříd, &lt;a href="http://martinfowler.com/eaaCatalog/repository.html"&gt;Repository&lt;/a&gt;, &lt;a href="http://martinfowler.com/eaaCatalog/queryObject.html"&gt;Query&lt;/a&gt; a &lt;a href="http://martinfowler.com/eaaCatalog/dataTransferObject.html"&gt;DTO&lt;/a&gt; tříd. Podle constraints definovaných v modelu jsme schopni nagenerovat i základní klientské validátory v javascriptu.&lt;br /&gt;&lt;h3&gt;DSL Tools&lt;/h3&gt;&lt;br /&gt;Po zdlouhavém úvodu se konečně dostáváme k věci. Protože je na českém internetu velmi málo zdrojů o DSL Tools, pokusil jsem se natočit vlastní screencast pro začátečníky. Má vás přenést přes vstupní bariéru a předvést základní kroky, které jsou nutné k vytvoření jednoduchého DSL jazyka. Sám jsem na začátku dost tápal, tak doufám že vám to ulehčí start. Je to můj první screencast, tak buďte prosím shovívaví (ano, dělám si alibi:-). DSL Tools jsou součástí &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=59EC6EC3-4273-48A3-BA25-DC925A45584D&amp;amp;displaylang=en"&gt;Visual Studio SDK&lt;/a&gt; a k vytváření jazyků je potřeba Professional edice. Pak je možné vytvořit add-in package do Visual Studia a k běžné práci s modelem by měla stačit Standard edice bez nutnosti instalovat SDK (modelovací runtime je od verze 2008 součástí Visual Studia). Zásahů do jazyka je potřeba poměrně málo, protože většinu problémů vyřešíte pouhou změnou tt šablony.&lt;br /&gt;&lt;br /&gt;Ve videu uvidíte, jak se nejdřív definuje DSL jazyk, a jak se vyzkouší v nové instanci Visual Studia. Kód se generuje pomocí &lt;a href="http://www.vyvojar.cz/Articles/631-sablony-t4.aspx"&gt;T4&lt;/a&gt; a zvýraznění syntaxe poskytuje &lt;a href="http://www.visualt4.com/"&gt;Clarius T4 Editor&lt;/a&gt; (plugin do Visual Studia).&lt;br /&gt;&lt;br /&gt;Jakmile překonáte vstupní bariéru, vše půjde hladce. Na netu jsou dostupná další &lt;a href="http://msdn.microsoft.com/en-us/vsx/cc677256.aspx"&gt;videa v angličtině&lt;/a&gt;, doporučuju také blog &lt;a href="http://www.olegsych.com/"&gt;Olega Sycha&lt;/a&gt; který se věnuje generování artefaktů pomocí T4 šablon a zná spoustu fíglů. Pokud to s DSL myslíte vážně, kupte si knížku &lt;a href="http://www.domainspecificdevelopment.com/"&gt;Domain-Specific Development with Visual Studio DSL Tools&lt;/a&gt;, to je asi nejlepší existující dokumentace.&lt;br /&gt;&lt;br /&gt;A co mám na DSL Tools nejradši? Že prostředí, ve kterém vytváříte váš DSL jazyk, je samo doménově-specifickým jazykem pro modelování DSL jazyků:-) Jinými slovy, meta-modelování a modelování používá totožný modelovací runtime. To co vytváříte v DSL projektu v souboru DslDefinition.dsl, je model vašeho jazyka, který je následně transformován pomocí tt šablon na C# kód, přeložen, nainstalován do experimental hive Visual Studia. Stejně pak funguje váš jazyk: Umožňuje vytvořit model, transformovat na kód, zkompilovat a spustit. Znamená to také, že váš DSL jazyk můžete lehce customizovat pomocí partial a double derived tříd. Není to žádný trik, ale starý dobrý C#. Dál to taky znamená, že vše co vidíte v DslDefinition.dsl (vzhled a layout diagramu, editory vlastností, validace modelu atd.) můžete použít i ve svém jazyku. Můžete si být jistí proto, že váš model poběží na stejném runtime jako designer DSL jazyka.&lt;br /&gt;&lt;br /&gt;Solution vytvořené ve videu: &lt;a href="http://www.kolman.cz/alibaba/res/SampleDsl.zip"&gt;SampleDsl.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="screencast"&gt;&lt;br /&gt;&lt;object width="640" height="498"&gt; &lt;param name="movie" value="http://content.screencast.com/users/danielkolman/folders/Default/media/820cf2c3-4ddc-4b92-ba95-53fc00522bc8/flvplayer.swf"&gt; &lt;param name="quality" value="high"&gt; &lt;param name="bgcolor" value="#FFFFFF"&gt; &lt;param name="flashVars" value="thumb=http://content.screencast.com/users/danielkolman/folders/Default/media/820cf2c3-4ddc-4b92-ba95-53fc00522bc8/FirstFrame.jpg&amp;amp;containerwidth=640&amp;amp;containerheight=498&amp;amp;content=http://content.screencast.com/users/danielkolman/folders/Default/media/820cf2c3-4ddc-4b92-ba95-53fc00522bc8/dsltools-scrcast.mp4"&gt; &lt;param name="allowFullScreen" value="true"&gt; &lt;param name="scale" value="showall"&gt; &lt;param name="allowScriptAccess" value="always"&gt; &lt;param name="base" value="http://content.screencast.com/users/danielkolman/folders/Default/media/820cf2c3-4ddc-4b92-ba95-53fc00522bc8/"&gt;  &lt;embed src="http://content.screencast.com/users/danielkolman/folders/Default/media/820cf2c3-4ddc-4b92-ba95-53fc00522bc8/flvplayer.swf" quality="high" bgcolor="#FFFFFF" type="application/x-shockwave-flash" allowscriptaccess="always" flashvars="thumb=http://content.screencast.com/users/danielkolman/folders/Default/media/820cf2c3-4ddc-4b92-ba95-53fc00522bc8/FirstFrame.jpg&amp;amp;containerwidth=640&amp;amp;containerheight=498&amp;amp;content=http://content.screencast.com/users/danielkolman/folders/Default/media/820cf2c3-4ddc-4b92-ba95-53fc00522bc8/dsltools-scrcast.mp4" allowfullscreen="true" base="http://content.screencast.com/users/danielkolman/folders/Default/media/820cf2c3-4ddc-4b92-ba95-53fc00522bc8/" scale="showall" width="640" height="498"&gt;&lt;/embed&gt; &lt;/object&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-5335360842495540809?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/3Tfb0PRnzY4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/5335360842495540809/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=5335360842495540809&amp;isPopup=true" title="Počet komentářů: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/5335360842495540809" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/5335360842495540809" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/3Tfb0PRnzY4/model-driven-development-v-praxi.html" title="Model Driven Development v praxi" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2009/03/model-driven-development-v-praxi.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-4027789676468410365</id><published>2009-02-07T14:55:00.004+01:00</published><updated>2009-02-07T15:44:05.383+01:00</updated><title type="text">O čem bych chtěl psát ale nemám na to čas</title><content type="html">&lt;p&gt;Od mého posledního ublognutí uplynulo mnoho LOC. Není to tím že bych neměl o čem psát, ale nějak se mi nedostává času. Tak alespoň ve stručnosti, na čem pracuju a o čem bych si v budoucnu chtěl ublognout:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Codename Ginger:&lt;/b&gt; Aplikační framework pro tvorbu distribuovaných (nejen) webových aplikací. Řeší architektonický základ takové aplikace: rozdělení do vrstev a vrstev (v češtině se dost špatně rozlišuje &lt;i&gt;layer&lt;/i&gt; a &lt;i&gt;tier&lt;/i&gt;), jazyk pro modelování domény vytvořený pomocí &lt;a href="http://msdn.microsoft.com/en-us/vsx/cc677256.aspx"&gt;DSL Tools&lt;/a&gt;, generování různých artefaktů jako skriptů pro vytvoření databáze, mapovacích souborů, doménových a DTO objektů přímo z modelu pomocí T4. Není to žádná chiméra, máme reálně fungující a solidně protestovanou verzi a vyvíjíme v tom komerční aplikace. Na webové vrstvě používáme ASP.NET MVC, na datové NHibernate a trochu jsme to okořenili Spring.Net (ale jen s citem). Velkou inspirací pro nás je &lt;a href="http://www.nservicebus.com/"&gt;NServiceBus&lt;/a&gt; a pak samozřejmě bible enterprise aplikací &lt;a href="http://martinfowler.com/books.html#eaa"&gt;Patterns of EAA&lt;/a&gt; od Martina Fowlera.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;WPF:&lt;/b&gt; Celkem dlouho jsem tuto technologii ignoroval, protože jsem někde četl že v ní není DataGrid. Hrozná chyba! Příliš mnoho času jsem strávil ve Windows Forms, takže jsem si nedokázal představit, jak flexibilní může být UI framework. Teď si to vynahrazuju. Jsem nadšen ze stylování, data bindingu a content modelu. Kromě toho, že v tom nejdou kloudně zobrazovat bitmapy, je to naprosté programátorské blaho.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Scrum:&lt;/b&gt; Snažím se v práci prosadit, abychom v příští verzi našeho produktu nasadili tuto metodologii. Máme trochu problém s plánováním, termíny a komunikací, a od Scrumu si slibuju, že budeme mít přesnější představu jak na tom jsme, zpřesníme plánování, díky projektovým tymům usnadníme komunikaci, vývojáři se budou moct lépe soustředit na výsledek a díky tomu také zvedneme kvalitu našeho kódu. Nehledě na to, že nás to bude víc bavit:-) Teorie je na webu dost, ale našel jsem &lt;a href="http://www.infoq.com/minibooks/scrum-xp-from-the-trenches"&gt;super knížku&lt;/a&gt;, která se věnuje praktické realizaci. Je zdarma, tak neváhejte a stahujte, je opravdu dobrá. Doufám že to vyjde a že budu moct časem ublognout jak nám to jde.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Tak to je ve zkratce všechno, mám v hlavě sice daleko víc nápadů, ale den má jen 24 hodin:-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-4027789676468410365?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/a2jRqotuD3A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/4027789676468410365/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=4027789676468410365&amp;isPopup=true" title="Počet komentářů: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/4027789676468410365" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/4027789676468410365" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/a2jRqotuD3A/od-meho-posledniho-ublognuti-uplynulo.html" title="O čem bych chtěl psát ale nemám na to čas" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2009/02/od-meho-posledniho-ublognuti-uplynulo.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-3437696049172870110</id><published>2008-08-28T22:34:00.005+02:00</published><updated>2008-08-29T07:28:32.725+02:00</updated><title type="text">Jak programovat bez ega</title><content type="html">Přestože mnozí věří, že programování je exaktní věda, ve skutečnosti má blíž k literatuře. Program se nedá vypočítat, program se musí napsat. Programátor musí, stejně jako spisovatel, psát jazykem kterému rozumí ostatní programátoři a dodržovat určitá stylistická pravidla. Počítačové jazyky totiž existují kvůli lidem a ne kvůli počítačům, ty by se spokojily s nulami a jedničkami. Větší pozornost je sice nutné věnovat kritickým (napínavým) úsekům, ale pokud autor ztratí ze zřetele soudržnost celku, výsledkem bude škvár, který sice možná bude sdělovat příběh, ale prokousat se jím bude peklo.&lt;br /&gt;&lt;br /&gt;Na rozdíl od spisovatelů jsou však programátoři nuceni pracovat v týmech. Mají tak problémy, kteří spisovatelé vůbec neznají. Některé jsou technického rázu a jdou celkem uspokojivě vyřešit, např. jak spojovat kusy napsané různými autory do jednoho celku (VCS). Horší vznikají tím, že programátoři jsou lidi. Lidská interakce je nesmírně složitá a ke strojové přesnosti a neutrálnosti má na hony daleko. Představte si to, kvůli mezilidským vztahům dokonce vzniklo několik vědních oborů (sociologie, psychologie, psychiatrie, politologie, ekonomie atd.)! Manažeři programátorů se navíc často domnívají, že se pohybují ve výhradně technické oblasti, a tak mohou problémy druhého typu v klidu nepovšimnuty bujet a stávat se patologickými. Ale to je jiná kapitola.&lt;br /&gt;&lt;br /&gt;Dnes se chci věnovat jedné vlastnosti, kterou mají programátoři se spisovateli společnou. Každý autor, ať už píše cokoliv, se se svým dílkem ztotožňuje. Je to naprosto přirozené: Trávíte s ním spoustu času, stojí vás mnoho úsilí a chcete aby se mu dařilo co nejlépe. Když pak přijde kritika, ať už oprávněná nebo ne, je těžké ji přijmout s chladnou hlavou. U spisovatelů to vede k úsměvným historkám ve společenských časopisech, u programátorů k frustraci a nepřátelství. A protože se programátoři potkávají v práci každý den, je to pro ně daleko horší problém než pro spisovatele. Pak je ale těžké napsat dobrý program.&lt;br /&gt;&lt;br /&gt;Jak tedy programovat bez ega? V první řadě musí člověk přijmout fakt, že se může mýlit. Vždy se najde někdo, kdo o daném problému ví víc než vy. Zvlášť když strávíte se svým produktem delší dobu, je těžké najít odstup a snadno pak přehlédnete i očividné chyby. Pravdu naopak mohou mít i lidé, od nichž by to člověk vůbec nečekal. A tak nezbývá než věnovat pozornost každé výtce, ať už pochází z jakéhokoliv zdroje. &lt;br /&gt;&lt;br /&gt;A opačně, pokud kritizujeme, snažme se nedotknout se osobnosti autora kódu. Kritizujte kód, ne jeho autora. Snažte se navrhovat, jakým způsobem lze kód vylepšit. Pokud je to možné, opřete se o fakta (standardy, měření, literatura, články na webu, dohodnuté konvence atd.). Destruktivní kritika typu "seš snad úplně blbej" nebo "všechno stojí za hovno" nikam nevede, jen šíří pocity zoufalství. Zkuste odhadnout, kolik toho ten druhý "skousne" a buďte hodní na kolegy, kteří nemají takové sebevědomí. To, že má někdo méně zkušeností nebo znalostí neznamená, že je horší než vy. Navíc za rok může být situace klidně opačná. Pokud tým funguje, jeho členové jsou schopni se navzájem učit a mají ze spolupráce dobrý pocit. &lt;br /&gt;&lt;br /&gt;Aby se programátoři nestyděli zeptat se kolegy o radu, musí v týmu panovat přesvědčení, že mýlit se je lidské a že víc hlav víc ví. Každý má občas špatný den a jediné co se s tím dá dělat, je umožnit, aby se na chyby přišlo co nejdříve. Dobrou pomůckou mohou být techniky z &lt;a href="http://www.extremeprogramming.org/map/development.html"&gt;extrémního programování&lt;/a&gt;, jako párové programování, code review, kolektivní vlastnictví kódu a stand-up meetingy (také známé jako &lt;a href="http://martinfowler.com/articles/itsNotJustStandingUp.html"&gt;scrum&lt;/a&gt;). Mám ale obavu, že prvotní je dobrý výběr lidí; nehledět při náboru pouze na technické znalosti, ale i na to, zda je přijímaný člověk týmový hráč. Pokud máte tým složený ze samých "&lt;a href="http://c2.com/cgi/wiki?HyperSensitiveCodeMachine"&gt;hyper-senzitivních code-machines&lt;/a&gt;", žádné metodologie vám asi nepomůžou.&lt;br /&gt;&lt;br /&gt;Já sám osobně mám pocit, že už dokážu obstojně snášet kritiku kódu, který jsem napsal. Kritizovat kód kolegů mně ale stále nejde tak, jak bych si představoval. Je těžké vybrat správná slova, aby druhý pochopil, že ho nechci urazit ani snížit jeho zásluhy. Někdy mě zradí jazyk, někdy se moc rozohním, někdy toho mám prostě dost a někdy zafunguje ponorková nemoc, protože pracuju ve firmě, kde jsou trvalé týmy - roky sedíte v kanceláři se stejnými lidmi. Tímto se proto omlouvám každému, koho jsem kdy mohl urazit a chci aby jste věděli, že kašlu na to kdo je autorem, zajímá mě pouze kód a aby byl dobrý.&lt;br /&gt;&lt;br /&gt;Ještě poznámka na závěr: Zajímavá je souvislost s jiným principem efektivního programování: Ukazuje se totiž, že programovat bez ega znamená napsat pouze tolik, kolik situace vyžaduje - ne méně a ne více. Nemá prostě cenu &lt;a href="http://c2.com/cgi/wiki?GoldPlating"&gt;vymýšlet všechny varianty&lt;/a&gt;, které by po nás mohl uživatel teoreticky chtít, a potom napsat nějaké úžasně univerzální über-řešení; lepší je napsat program, který řeší pouze aktuální problém, a pokud bude potřeba, bude se průběžně doplňovat a zesložiťovat. Je to staré pravidlo YAGNI (You Ain't Gonna Need It), které jinými slovy říká, že i když jste bůhvíjak dobří programátoři, nesmíte se bát obyčejných jednoduchých řešení - není to ostuda.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://c2.com/cgi/wiki?EgolessProgramming"&gt;Egoless Programming&lt;/a&gt;&lt;br /&gt;&lt;a href="http://articles.techrepublic.com.com/5100-10878_11-1045782.html"&gt;Ten Commandments of Egoless Programming&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-3437696049172870110?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/coRxe_QHWMg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/3437696049172870110/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=3437696049172870110&amp;isPopup=true" title="Počet komentářů: 5" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/3437696049172870110" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/3437696049172870110" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/coRxe_QHWMg/jak-programovat-bez-ega.html" title="Jak programovat bez ega" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2008/08/jak-programovat-bez-ega.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-789689129623579642</id><published>2008-07-26T00:20:00.005+02:00</published><updated>2008-07-26T10:42:38.354+02:00</updated><title type="text">Ornament a kód</title><content type="html">Ornament je zločin, vytanula mi na mysl slova Adolfa Loose, když jsem brousil starou olouhovanou skříň. Má totiž několik ozdobných vlnek, které bylo potřeba pracně ručně obrušovat každou zvlášť. A pak mě napadlo, že to vlastně platí víc v programování než v architektuře.&lt;br /&gt;&lt;br /&gt;Nejdřív mi dovolte stručné vysvětlení úvodního citátu (čtenáři s humanitním vzděláním laskavě prominou):&lt;br /&gt;&lt;br /&gt;Moderní architekti prohlásili dům za stroj na bydlení (*1). Architektura podle nich není umění, ale věda o bydlení, která má upravit hmotné prostředí potřebám lidského živočicha. Nenávist k ornamentu je logickým důsledkem tohoto názoru - vždyť k čemu jsou lidem propracované ozdobičky, když vše co potřebují je čerstvý vzduch, dostatek slunce, teplo a bydlení v obytné zóně bez továren? "Less is more" (Mies van der Rohe) se stalo heslem několika generací architektů. Le Corbusier řekl: „Dekorace je smyslné a primitivní povahy, stejně jako barva, a hodí se toliko pro nižší třídy, sedláky a divochy.“ &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bc.edu/bc_org/avp/cas/fnart/Corbu.html"&gt;&lt;br /&gt;&lt;img src="http://www.kolman.cz/alibaba/res/savoye2.jpg" /&gt;&lt;br /&gt;copyright Jeffery Howe&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Adolf Loos i Le Corbusier sice zapomněli že lidé v domech nejen bydlí, ale také chodí kolem, přesto však udělali se svým názorem díru do světa. Podařilo se jim přesvědčit ostatní o své pravdě a  nadlouho ovlivnili myšlení architektů a urbanistů na celém světě. Důsledky známe i u nás v podobě uniformních panelových sídlišť, které přímo vycházejí z jejich ideálů - i když s jejich provedením by asi Le Corbusier nesouhlasil. Konec dominance funkcionalistické architektury znamenal až nástup postmoderny v šedesátých letech a "less is more" nahradil Robert Venturi heslem "less is bore".&lt;br /&gt;&lt;br /&gt;&lt;a href="http://commons.wikimedia.org/wiki/Image:CasaBatllo_0170.JPG"&gt;&lt;br /&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/commons/thumb/6/6b/CasaBatllo_0170.JPG/398px-CasaBatllo_0170.JPG" /&gt;&lt;br /&gt;copyright tato grasso&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A jak to souvisí s programováním? Každý, kdo někdy četl cizí kód, si hned všimne nezvyklých konstrukcí a způsobu formátování kódu. Někdy zaujme precizní tabulární formátování, někdy tvrdošíjná maďarská notace, jindy zas poznámky ve kterých vede programátor dialog sám se sebou. To vše odvádí pozornost čtenáře od funkce k formě. Nejsou to snad ornamenty? &lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.kolman.cz/alibaba/res/ProtectedFields.png" /&gt;&lt;br /&gt;&lt;br /&gt;Zdálo by se že tu ornamenty hájím, protože vnášejí krásu do všednosti, vítané potěšení znavenému duchu. Jenže mezi programováním a architekturou je jeden podstatný  rozdíl. Architekt musí počítat s tím, že kolem jeho děl budou chodit i laici, kteří o zločinnosti ornamentu nemají nejmenšího tušení. Architekt by měl prostředí ušít na míru všem, nejen kolegům z branže a odborné kritice. Vhodně zvolený ornament pak může sloužit jako vodítko i (z architektova hlediska) nevzdělanému tupci, který by jinak jeho střízlivý obytný dům mohl považovat za vězení.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.kolman.cz/alibaba/res/FillerCode.png" /&gt;&lt;br /&gt;&lt;br /&gt;Kolem vašeho kódu ale laici chodit nebudou. Váš kód se dostane do ruky úzké skupině lidí s (někdy až příliš) specializovaným výcvikem, kteří budou mít za úkol se v něm zorientovat a provést potřebné změny. Pro ně je jakýkoliv ornament zdržením. Nejčitelnější kód je takový, který se striktně drží stanovených konvencí. Kód by měl vypadat tak, jako kdyby ho napsal jeden programátor během jednoho sezení.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.kolman.cz/alibaba/res/RecognizeBool.png" /&gt;&lt;br /&gt;&lt;br /&gt;Ornament v kódu je jakékoliv porušení stanovených konvencí. Napíšete-li kus kódu jinak, než je ve vašem týmu obvyklé, nutíte kolegy aby při čtení této části kódu přemýšleli ne o tom, co kód dělá, ale o jeho formátování - proč je zapsán tímto neobvyklým způsobem? Je za tím nějaká myšlenka, která mi uniká? Něco na co chtěl autor upozornit? Bohužel, většinou se jedná jen o neznalost konvencí, okamžitý nápad jak kód napsat "lépe" (v lepším případě), nebo o přesvědčení autora že jeho konvence jsou lepší a ostatní by je měli přijmout.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.kolman.cz/alibaba/res/Smola.png" /&gt;&lt;br /&gt;&lt;br /&gt;Jak mají vypadat konvence psaní kódu je sice sporná věc, ale jakmile se na nějakých shodnete, je nutné je dodržovat. Osobně preferuju držet se výchozích nastavení Visual Studia a ReSharperu. Proč pracně přenastavovat něco, co používají tisíce programátorů na celém světě? Tím odpadne mnoho diskusí ohledně formátování závorek a mezer kolem operátorů. Mnoho dalších věcí za vás nástroje nevyřeší (jmenné konvence, pořadí prvků atd.), ale na internetu je spoustu zdrojů a vzorových "code conventions" dokumentů i pro váš programovací jazyk. &lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.kolman.cz/alibaba/res/UltraPolymorphism.png" /&gt;&lt;br /&gt;&lt;br /&gt;Kód odpovídá strukturálním a technickým stránkám budovy. Je to nosný systém, vodotěsné zastřešení, rozvody energie a vody, výtahy. Pokud chcete postavit dobrý dům, je bezpodmínečně nutné udělat tyto základní věci dobře a umožnit údržbářům snadný přístup ke všem důležitým bodům. Na stavbě si nemůžete vymyslet svůj vlastní a  zcela nový systém elektrických rozvodů a pojistek, nedělejte to ani v kódu. Na Grand Prix Obce architektů to sice nestačí, ale bez dobrého základu nepostavíte ani kůlnu. Dodržování konvencí zdaleka není všechno, ale usnadní život vašim kolegům (a také vám, až se budete za rok divit proč jste to tenkrát takhle napsali). Nechte si ornamenty do uživatelského rozhraní, ve stylistické úpravě kódu platí "bore is more".&lt;br /&gt;&lt;br /&gt;*1 Le Corbusier ([1923] 1952): Towards a New Architecture. London&lt;br /&gt;*2 &lt;a href="http://cs.wikipedia.org/wiki/Funkcionalismus"&gt;http://cs.wikipedia.org/wiki/Funkcionalismus&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;UPDATED: 2008-07-26 Přidány citáty Mies van der Rohe a Roberta Venturiho.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-789689129623579642?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/azAP0n9-OCw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/789689129623579642/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=789689129623579642&amp;isPopup=true" title="Počet komentářů: 2" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/789689129623579642" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/789689129623579642" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/azAP0n9-OCw/ornament-kd.html" title="Ornament a kód" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2008/07/ornament-kd.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-2265961465363035751</id><published>2008-07-09T22:31:00.002+02:00</published><updated>2008-07-09T22:54:44.608+02:00</updated><title type="text">Přednáška o CruiseControl.Net a MSBuild</title><content type="html">Dneska jsem dělal interní přednášku pro kolegy ve firmě o průběžné integraci s pomocí &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET"&gt;CruiseControl.Net&lt;/a&gt; a &lt;a href="http://msdn.microsoft.com/en-us/library/wea2sca5.aspx"&gt;MSBuild&lt;/a&gt;, a o našem build systému postaveném na těchto technologiích. PowerPointovou prezentaci si díky laskavému svolení mého zaměstnavatele můžete stáhnout &lt;a href="res/ci.pps"&gt;zde&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Jediné co nám chybí k dokonalému build systému je &lt;a href="http://code.google.com/p/bigvisiblecruise/"&gt;Big Visible Cruise&lt;/a&gt; nebo &lt;a href="http://www.agileskunkworks.org/home/Articles/TheOrbBuildIndicatorLamp/tabid/114/Default.aspx"&gt;The Orb&lt;/a&gt;. Ale až budu mít trochu času, chtěl bych nějakou takovou hračku pořídit;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-2265961465363035751?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/NQtH3ACzrNI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/2265961465363035751/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=2265961465363035751&amp;isPopup=true" title="Počet komentářů: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/2265961465363035751" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/2265961465363035751" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/NQtH3ACzrNI/pednka-o-cruisecontrolnet-msbuild.html" title="Přednáška o CruiseControl.Net a MSBuild" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2008/07/pednka-o-cruisecontrolnet-msbuild.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-4436198591775447891</id><published>2008-06-24T17:43:00.002+02:00</published><updated>2008-06-24T17:52:46.163+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="kafe" /><title type="text">Jak udělat espresso</title><content type="html">Protože mně &lt;a href="http://www.nikdo.cz/"&gt;Nikdo&lt;/a&gt; předal štafetu, tady je moje oblíbené video: Jak správně na espresso. Mimochodem, mají tam nádhernou mašinku. Jednou bych chtěl takovou doma:-) &lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/O2b8uB4russ&amp;hl=en"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/O2b8uB4russ&amp;hl=en" type="application/x-shockwave-flash" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Kafe které tam používají (Ethiopia Sidamo) se dá sehnat i u nás, např. já ho kupuju v &lt;a href="http://www.mamacoffee.cz/"&gt;Mama Coffee&lt;/a&gt; kde ho mají v super kvalitě a za rozumnou cenu.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-4436198591775447891?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/bG7zm2tTNys" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/4436198591775447891/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=4436198591775447891&amp;isPopup=true" title="Počet komentářů: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/4436198591775447891" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/4436198591775447891" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/bG7zm2tTNys/jak-udlat-espresso.html" title="Jak udělat espresso" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2008/06/jak-udlat-espresso.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-1751174470576392498</id><published>2008-06-20T08:13:00.004+02:00</published><updated>2008-06-20T08:33:23.704+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate" /><title type="text">Když Já není Já</title><content type="html">Nebojte, nebudu tu rozebírat schizofrenní poruchy vyvolané dlouhodobým zíráním do monitoru. Jde o klíčové slovo &lt;span class="code"&gt;this&lt;/span&gt; v C# a o jeden zajímavý případ, kdy &lt;span class="code"&gt;this&lt;/span&gt; není &lt;span class="code"&gt;this&lt;/span&gt;, nebo alespoň není to &lt;span class="code"&gt;this&lt;/span&gt;, které jsme si mysleli že bude.&lt;br /&gt;&lt;br /&gt;Pro začátek si představte, že máte dva objekty, mezi kterými je obousměrná vazba 1-N. Například &lt;span class="code"&gt;User&lt;/span&gt; a &lt;span class="code"&gt;Task&lt;/span&gt;, tedy uživatel a jeho úkoly, kde úkol může být přidělen nejvýše jednomu uživateli:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class User &lt;br /&gt;{&lt;br /&gt; IList&lt;Task&gt; _tasks;&lt;br /&gt; public IList&lt;Task&gt; Tasks&lt;br /&gt; {&lt;br /&gt;  get { return _tasks; }&lt;br /&gt;  set { _tasks = value; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Task&lt;br /&gt;{&lt;br /&gt; User _holder;&lt;br /&gt; public User Holder&lt;br /&gt; {&lt;br /&gt;  get { return _holder; }&lt;br /&gt;  set { _holder = value; }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; ... etc ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Protože nepracujeme ve státním sektoru, Tasků je hodně a je nutné, aby si naše aplikace pamatovala úkoly uživatelů i zítra. Použijeme tedy nějakou databázi; tím myslím existující databázový systém, který si stáhneme z internetu (MS SQL Express, MySQL apod.). Nezačneme tedy implementací vlastního RDMS, ani nebudeme simulovat databázi pomocí mnoha XML souborů uložených kdesi na disku (asi se divíte proč se s tím tak rozepisuju, ale nevěřili by jste, kolik lidí nemá rádo databáze, co si sami nenapsali).&lt;br /&gt;&lt;br /&gt;A protože jsme vychytralí, použijeme nějaký O/RM nástroj pro mapování objektů do databáze. A jelikož nejsme bohatí, bude to NHibernate, který je zdarma, a podporuje víc databází než LINQ to SQL (navíc jsme chudí takže stále pracujeme ve Visual Studiu 2005 kde není podpora lambda výrazů).&lt;br /&gt;&lt;br /&gt;Když budeme tedy chtít přiřadit Task nějakému uživateli, náš kód bude vypadat nějak takhle:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;// odněkud vytáhneme volný Task&lt;br /&gt;Task task = TaskRepository.GetNextUnassignedTask();&lt;br /&gt;// najdeme uživatele, který nemá co na práci&lt;br /&gt;User user = UserRepository.GetUserReadingBlogsButNotMine();&lt;br /&gt;// a dáme mu úkol, ať se snaží hošánek (nebo frajerka)&lt;br /&gt;task.Holder = user;&lt;br /&gt;user.Tasks.Add(task); // zachováme obousměrnost vazby, aby se další kód mohl bez problémů odkazovat na user.Tasks&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ha. Funguje to. Něco tu ale smrdí. Ano, jsou to ty dva řádky, které nastavují vazbu mezi Userem a Taskem. Nestačil by jeden? Jak známe kolegu X., určitě někde druhý řádek zapomene (nám by se to samozřejmě nestalo), a pak bude od tohoto bodu dále v paměti strašit inkonzistence dat, až do ukončení databázové &lt;span class="code"&gt;ISession&lt;/span&gt;. Pak může snadno nastat chyba úplně na jiném místě a než na to přijdeme, ujmou se nás psychoterapeuti. Zkusíme tedy, ach my bláhoví, upravit property Holder:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Task&lt;br /&gt;{&lt;br /&gt; User _holder;&lt;br /&gt; public User Holder&lt;br /&gt; {&lt;br /&gt;  get { return _holder; }&lt;br /&gt;  set {&lt;br /&gt;   if(_holder!=value)&lt;br /&gt;   {&lt;br /&gt;    if(_holder!=null)&lt;br /&gt;     _holder.Tasks.Remove(this);&lt;br /&gt;    _holder = value; &lt;br /&gt;    if(_holder!=null)&lt;br /&gt;     _holder.Tasks.Add(this);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; ... etc ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ponechme teď stranou fakt, že pokud to samé uděláme v &lt;span class="code"&gt;User.Tasks.Add()&lt;/span&gt;, nastane nekonečná smyčka kterou ukončí až milosrdné přetečení zásobníku nebo jiná populární výjimka (ve skutečnosti budeme chtít z objektu &lt;span class="code"&gt;User&lt;/span&gt; publikovat pouze read-only wrapper kolekce &lt;span class="code"&gt;Tasks&lt;/span&gt;, protože to bude inverzní konec asociace, který není ukládán do databáze). Přejděme mlčky i problém inicializace objektu &lt;span class="code"&gt;Task&lt;/span&gt; při jeho nahrávání z databáze, kdy kolekce &lt;span class="code"&gt;_holder.Task&lt;/span&gt; ještě nebude inicializovaná a přidáním tasku do ní si připravíme pozdější muka při nahrávání kolekce z databáze (to se dá řešit, viz např. třída &lt;span class="code"&gt;PersistentGenericBag&amp;lt;T&amp;gt;&lt;/span&gt; a její metoda &lt;span class="code"&gt;DelayedAddAll&lt;/span&gt; v NHibernate).&lt;br /&gt;&lt;br /&gt;Leč je tu ještě daleko zákeřnější past: &lt;span class="code"&gt;this&lt;/span&gt; není &lt;span class="code"&gt;this&lt;/span&gt; které potřebujeme. Jak je to možné? Protože používáme lazy loading našich objektů. Je velmi pravděpodobné, že místo objektu task dostaneme proxy objektu task. Náš milý task proto nebude instance typu &lt;span class="code"&gt;Task&lt;/span&gt;, ale typu s krásným názvem &lt;span class="code"&gt;CProxyTypeTest_BidirectionalTestTaskDomain_NHibernate_ProxyINHibernateProxy1&lt;/span&gt;, nebo podobně pojmenovaného. Tento typ je dynamicky vygenerovaný potomek našeho typu Task a slouží jako proxy, která nahraje task z databáze teprve když je to potřeba. Když je proxy třída odvozená z naší třídy, v čem je tedy problém? V tom, že objekt task NENÍ proxy objekt; v programátorštině mezi nimi není referenční identita. Proxy objekt totiž neukládá data do sebe, ale obsahuje referenci na náš objekt a přeposílá mu veškerá volání metod a vlastností (a zpátky předává návratovou hodnotu). Aby to nebylo tak jednoduché, mezi proxy a naším taskem stojí ještě další objekt, tentokrát typu &lt;span class="code"&gt;CastleLazyInitializer&lt;/span&gt; z NHibernate. Ale to už zabíhám do detailů.&lt;br /&gt;&lt;br /&gt;Podívejme se teď znovu na první verzi kódu a přidejme jednu celkem logickou kontrolu výsledku:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;// odněkud vytáhneme volný Task&lt;br /&gt;Task task = TaskRepository.GetNextUnassignedTask(); &lt;strong&gt;// vrací proxy objektu Task&lt;/strong&gt;&lt;br /&gt;// najdeme uživatele, který nemá co na práci&lt;br /&gt;User user = UserRepository.GetUserReadingBlogsButNotMine();&lt;br /&gt;// a dáme mu úkol, ať se snaží hošánek (nebo frajerka)&lt;br /&gt;task.Holder = user;&lt;br /&gt;user.Tasks.Add(task); // do user.Tasks přidáváme &lt;strong&gt;proxy&lt;/strong&gt; objektu Task&lt;br /&gt;&lt;strong&gt;// zkontrolujeme zda je task součást uživatelových úkolů&lt;br /&gt;Assert.IsTrue(user.Tasks.Contains(task)); // OK&lt;/strong&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Protože se NHibernate chová jako správná Identity Map, vrací v rámci jedné session reference konzistentně, tj. pokud se na několika místech budete dotazovat různým způsobem na jeden Task, dostanete vždy odkaz buď na objekt samotný, nebo na stejnou proxy; mezi vrácenými objekty funguje referenční integrita. To znamená, že &lt;span class="code"&gt;user.Tasks.Contains(task)&lt;/span&gt; bude fungovat a vrátí správně true.&lt;br /&gt;&lt;br /&gt;A nyní se podívejme, co se stane když necháme přidání tasku do kolekce na property setteru &lt;span class="code"&gt;Holder&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;// odněkud vytáhneme volný Task&lt;br /&gt;Task task = TaskRepository.GetNextUnassignedTask(); // vrací proxy objektu Task&lt;br /&gt;// najdeme uživatele, který nemá co na práci&lt;br /&gt;User user = UserRepository.GetUserReadingBlogsButNotMine();&lt;br /&gt;// a dáme mu úkol, ať se snaží hošánek (nebo frajerka)&lt;br /&gt;task.Holder = user; &lt;strong&gt;// task je proxy, ve skutečnosti zprostředkuje volání property setteru našeho objektu&lt;/strong&gt;&lt;br /&gt;// zkontrolujeme zda je task součást uživatelových úkolů&lt;br /&gt;Assert.IsTrue(user.Tasks.Contains(task)); &lt;strong&gt;// FAIL!!!&lt;/strong&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A zde je jádro pudla: co se ve skutečnosti stane se dá opsat jako &lt;span class="code"&gt;task.ProxiedObject.Holder = user;&lt;/span&gt;. Uvnitř property setteru &lt;span class="code"&gt;Holder&lt;/span&gt; proto &lt;span class="code"&gt;this&lt;/span&gt; ukazuje na náš objekt, ne na proxy. Do kolekce &lt;span class="code"&gt;user.Tasks&lt;/span&gt; se přidá náš objekt Task, ne proxy v proměnné task. Vypadá to celkem nevinně, protože v tu chvíli už bude náš objekt inicializovaný (přistupujeme na property &lt;span class="code"&gt;task.Holder&lt;/span&gt;), ale je nutné si uvědomit, že přestává fungovat referenční integrita a tím porušujeme správné fungování Identity Map. Volání metody &lt;span class="code"&gt;user.Tasks.Contains(task)&lt;/span&gt; na dalším řádku vrátí false, přesto že je náš objekt Task v kolekci a v proměnné task je proxy ukazující na náš objekt. Kolekce &lt;span class="code"&gt;user.Tasks&lt;/span&gt; prostě obsahuje &lt;span class="code"&gt;task.ProxiedObject&lt;/span&gt; a ne task.&lt;br /&gt;&lt;br /&gt;Zajímavé je podívat se na stack trace v property setteru Task.Holder. Ukazuje, jak se jednoduché volání &lt;span class="code"&gt;task.Holder&lt;/span&gt; přesměruje přes proxy a interceptor (&lt;span class="code"&gt;CastleLazyInitializer&lt;/span&gt;):&lt;br /&gt;&lt;br /&gt;&lt;span class="code"&gt;&lt;br /&gt;BidirectionalTest.dll!BidirectionalTest.Task.Holder.set(BidirectionalTest.User value = {BidirectionalTest.User}) Line xxx C#&lt;br /&gt;&lt;br /&gt;[Native to Managed Transition] &lt;br /&gt;&lt;br /&gt;[Managed to Native Transition] &lt;br /&gt;&lt;br /&gt;Castle.DynamicProxy.dll!Castle.DynamicProxy.Invocation.AbstractInvocation.Proceed(object[] args = {Dimensions:[1]}) + 0x76 bytes &lt;br /&gt;&lt;br /&gt;NHibernate.dll!NHibernate.Proxy.CastleLazyInitializer.Intercept(Castle.DynamicProxy.IInvocation invocation = {Castle.DynamicProxy.Invocation.SameClassInvocation}, object[] args = {Dimensions:[1]}) + 0xc5 bytes &lt;br /&gt;&lt;br /&gt;DynamicAssemblyProxyGen!CProxyTypeTest_BidirectionalTestTaskDomain_NHibernate_ProxyINHibernateProxy1.Holder.set(BidirectionalTest.User value = {BidirectionalTest.User}) + 0xb3 bytes &lt;br /&gt;&lt;br /&gt;BidirectionalTest.dll!BidirectionalTest.Bidirectional1NIntegrationTest.Update_ChangesTargetCollection() Line 77 + 0xb bytes C#&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A nyní možná trochu překvapivý závěr: Celou tuhle anabázi jsme podstoupili jen proto, že nám nevoněl jeden řádek navíc. Protože se ale synchronizace druhých konců obousměrných asociací (to samé platí i pro many-to-many) ukázala jako plná mnoha problémů, zatím její řešení odsouvám na neurčito. Nemám čas zabývat se problémy, pro které existuje tak jednoduchý workaround. Nejde jen o proxy, ale také o read-only wrappery inverzních konců, rekurzivní smyčky a load time vs. run time, ale také o vlastní typy persistentních  kolekcí implementujících &lt;span class="code"&gt;IList&amp;lt;T&amp;gt;&lt;/span&gt; (místo PersistentGenericBag&amp;lt;T&amp;gt; a spol.), pokud bychom chtěli synchronizovat druhý konec many-to-many asociace při volání Add a Remove (i to je v NHibernate možné, ale je to trochu kostrbaté).&lt;br /&gt;&lt;br /&gt;Navíc je tu ještě jedno hledisko, performance. Je třeba si uvědomit, že pokud odebírám prvek z inverzního konce kolekce (nebo přidávám prvek v případě set a idbag), je nutné nejdřív tuto kolekci načíst do paměti, a to většinou zcela zbytečně! Inverzní konce se totiž nijak neukládají. Problém pak ale zůstává, jak chránit další kód ve stejné session proti nekonzistenci dat.&lt;br /&gt;&lt;br /&gt;Budu rád pokud zjistím že se pletu a někdo mi napíše jednoduchý způsob jak v NHibernate synchronizaci provést.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-1751174470576392498?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/_FxjNCkvESA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/1751174470576392498/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=1751174470576392498&amp;isPopup=true" title="Počet komentářů: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/1751174470576392498" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/1751174470576392498" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/_FxjNCkvESA/kdy-j-nen-j.html" title="Když Já není Já" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2008/06/kdy-j-nen-j.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-1036177088493952697</id><published>2007-09-14T16:17:00.000+02:00</published><updated>2007-09-14T16:42:39.773+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate" /><title type="text">NHibernate, lazy proxy třídy a chyba C# kompilátoru</title><content type="html">Kompilátor C# v .NET verze 2.0 obsahuje chybu, díky které při použití &lt;span class="code"&gt;where T : class&lt;/span&gt; pro omezení typového parametru generické třídy vygeneruje špatný IL kód. Díky tomu se takovou assembly vůbec nepodaří nahrát do paměti, runtime vyhodí výjimku: &lt;br /&gt;&lt;span class="code"&gt;&lt;br /&gt;System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Popis naleznete na &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93389" target="_blank"&gt;Microsoftu&lt;/a&gt; nebo taky na &lt;a href="http://www.ayende.com/Blog/archive/2006/07/21/7406.aspx" target="_blank"&gt;Ayendeho blogu&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Když používáte NHibernate, a zvlášť pokud jste právě přešli na verzi 1.2, může se tato výjimka objevit i když vůbec &lt;span class="code"&gt;where T : class&lt;/span&gt; nepoužijete. Jak to? NHibernate vám při načtení objektu může místo vaší třídy vrátit dynamicky generovanou proxy třídu (a ve verzi 1.2 je to default). V ní jsou všechny virtual members nahrazeny proxy metodou, která při prvním přístupu k objektu tento objekt načte z databáze (materializuje). No a když ve vašem objektu použijete virtuální metodu s generickým parametrem, např:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;protected virtual T GetProperty&amp;lt;T&amp;gt;(string name)&lt;br /&gt;{&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;snadno se dopracujete k výše zmíněné výjimce. Je to pravděpodobně (hlouběji jsem to nezkoumal) způsobeno tím, že generátor dynamické proxy třídy (Castle.DynamicProxy.dll) se pokouší emitovat kód, který podmínku &lt;span class="code"&gt;where T : class&lt;/span&gt; obsahuje, a pokus nahrát tuto třídu do paměti skončí s chybou. Proto používáte-li NHibernate a "lazy" načítání objektů, nepoužívejte virtuální generické metody.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-1036177088493952697?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/R2LmR79qfmo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/1036177088493952697/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=1036177088493952697&amp;isPopup=true" title="Počet komentářů: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/1036177088493952697" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/1036177088493952697" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/R2LmR79qfmo/nhibernate-lazy-proxy-tdy-chyba-c.html" title="NHibernate, lazy proxy třídy a chyba C# kompilátoru" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2007/09/nhibernate-lazy-proxy-tdy-chyba-c.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-3377166272267326325</id><published>2007-04-16T11:12:00.000+02:00</published><updated>2007-04-16T13:17:40.410+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ViewState" /><category scheme="http://www.blogger.com/atom/ns#" term="GridView" /><title type="text">Jak může GridView přijít o ViewState</title><content type="html">&lt;em&gt;Aneb o side-effectech, CompositeDataBoundControl-ech a Watch okně.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Minulý týden jsem řešil zapeklitý problém: &lt;span class="code"&gt;GridView&lt;/span&gt; občas při postbacku ztratilo řádky, tj. nenačetlo je správně z ViewState. Ovládací prvek, ve kterém bylo &lt;span class="code"&gt;GridView&lt;/span&gt; použito, přitom na jiných webových stránkách fungoval bez problémů.&lt;br /&gt;&lt;br /&gt;Nejdřív jsem pátral po vytváření ViewState a jeho ukládání do stránky a načítání při postbacku. Máme totiž poměrně složitou infrastrukturu odvozenou od třídy &lt;span class="code"&gt;Page&lt;/span&gt;, která se nechová úplně standardně a občas vyvádí psí kusy. Jenže se to ukázalo jako špatná stopa: ViewState byl normálně uložen a přítomen ve skrytém poli v postbacku. Jeho struktura vypadala dobře, zdálo se, že jej prostě &lt;span class="code"&gt;GridView&lt;/span&gt; ignoruje.&lt;br /&gt;&lt;br /&gt;Trochu jsem se porejpal ve zdrojových kódech .NETu (God Bless The &lt;a href="http://www.aisto.com/roeder/dotnet/" target="_blank"&gt;Reflector&lt;/a&gt;) a přišel jsem na to, že &lt;span class="code"&gt;GridView&lt;/span&gt; má dceřinný ovládací prvek typu &lt;span class="code"&gt;Table&lt;/span&gt;, který při postbacku dostane svůj ViewState a stará se o správnou rekonstrukci řádek tabulky. To znamená, že tento dceřinný prvek musí být vytvořen nejpozději v &lt;span class="code"&gt;OnLoad&lt;/span&gt;. Jenže na mé stránce měl v události &lt;span class="code"&gt;OnLoad&lt;/span&gt; můj &lt;span class="code"&gt;GridView&lt;/span&gt; prázdnou kolekci &lt;span class="code"&gt;Controls&lt;/span&gt;, ale přitom jeho &lt;span class="code"&gt;ChildControlsCreated&lt;/span&gt; bylo true. Když neexistuje dceřinný prvek &lt;span class="code"&gt;Table&lt;/span&gt;, nemá ani co nahrát ViewState.&lt;br /&gt;&lt;br /&gt;Zajímavé přitom bylo, že pokud jsem ve Watch okně Visual Studia změnil &lt;span class="code"&gt;ChildControlsCreated&lt;/span&gt; na false, okamžitě se přepsalo zpět na true a do kolekce &lt;span class="code"&gt;Controls&lt;/span&gt; se přidal prvek typu &lt;span class="code"&gt;Table&lt;/span&gt;! Chvíli jsem přemýšlel o woodoo a černé magii, pak jsem si ale prošel seznam ostatních položek ve Watch okně a začal jsem je zkoumat. Na první pohled nic podezdřelého neobsahovalo. Když jsem z něj ale odebral položku &lt;span class="code"&gt;Controls.Count&lt;/span&gt;, toto podivné chování ustalo a &lt;span class="code"&gt;ChildControlsCreated&lt;/span&gt; se klidně nechalo nastavit na false.&lt;br /&gt;&lt;br /&gt;Vrátil jsem se proto s Reflectorem do kódu a našel jsem zajímavý side effect při přistupování na kolekci &lt;span class="code"&gt;Controls&lt;/span&gt;, zavedený třídou &lt;span class="code"&gt;CompositeDataBoundControl&lt;/span&gt;: Před vrácením kolekce se volá &lt;span class="code"&gt;EnsureChildControls()&lt;/span&gt;! To vysvětluje ono podivné chování ve Watch okně, kde jsem měl kromě jiného i &lt;span class="code"&gt;Controls.Count&lt;/span&gt;. Když jsem přepsal &lt;span class="code"&gt;ChildControlsCreated&lt;/span&gt; na false, Visual Studio se pokusilo o refresh všech položek Watch okna, takže přístupem na kolekci &lt;span class="code"&gt;Controls&lt;/span&gt; spustilo i metodu &lt;span class="code"&gt;EnsureChildControls()&lt;/span&gt;, která nastavila &lt;span class="code"&gt;ChildControlsCreated&lt;/span&gt; zpět na true.&lt;br /&gt;&lt;br /&gt;A bylo jasno! Pokud přistoupím na kolekci &lt;span class="code"&gt;Controls&lt;/span&gt; před natažením ViewState (tedy před &lt;span class="code"&gt;OnLoad&lt;/span&gt;), způsobím volání metody &lt;span class="code"&gt;EnsureChildControls()&lt;/span&gt;. Ta zavolá &lt;span class="code"&gt;CreateChildControls()&lt;/span&gt;, ale pouze při prvním spuštění. No a &lt;span class="code"&gt;CreateChildControls()&lt;/span&gt; nevytvoří žádný ovládací prvek, pokud nemá k disposici ViewState! Takže &lt;span class="code"&gt;GridView&lt;/span&gt; nemá dceřinný prvek &lt;span class="code"&gt;Table&lt;/span&gt; který načítá ViewState a ani jej nevytvoří, protože už je označená jako &lt;span class="code"&gt;ChildControlsCreated&lt;/span&gt;=true.&lt;br /&gt;&lt;br /&gt;Z toho, děti, plynou následující poučení: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;Používáte-li ViewState, nepřistupujte na kolekci &lt;span class="code"&gt;Controls&lt;/span&gt; před událostí &lt;span class="code"&gt;OnLoad&lt;/span&gt;. Platí to pro všechny potomky &lt;span class="code"&gt;CompositeDataBoundControl&lt;/span&gt;, tedy &lt;span class="code"&gt;GridView&lt;/span&gt;, &lt;span class="code"&gt;FormView&lt;/span&gt; a &lt;span class="code"&gt;DetailsView&lt;/span&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Dávejte si pozor na to, co máte ve Watch okně, neboť to může mít (blahý i neblahý) efekt na běh kódu.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;PS: Poslal jsem to jako &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=271137" target="_blank"&gt;bug na Microsoft&lt;/a&gt;, jsem zvědavej jak se s tím hoši poperou.&lt;br /&gt;PPS: Nemusej to bejt jen hoši, koukal jsem nedávno na jeden &lt;a href="http://channel9.msdn.com/showpost.aspx?postid=295919" target="_blank"&gt;rozhovor na Channel9&lt;/a&gt; s Politou Paulus a má na stole (teda na okně:-) ocenění za návrh architektury DataBoundControls, takže možná je to její práce.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-3377166272267326325?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/Uff9qqNimyk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/3377166272267326325/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=3377166272267326325&amp;isPopup=true" title="Počet komentářů: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/3377166272267326325" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/3377166272267326325" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/Uff9qqNimyk/jak-me-gridview-pijt-o-viewstate.html" title="Jak může GridView přijít o ViewState" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2007/04/jak-me-gridview-pijt-o-viewstate.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-115866276467054335</id><published>2006-09-19T12:22:00.000+02:00</published><updated>2007-04-16T13:01:22.917+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><title type="text">Jak retardovat VS2005</title><content type="html">Visual Studio 2003 blahé paměti, nechť je mu země lehká, automaticky označovalo právě otevřený soubor v Solution Exploreru. Mnoho lidí na to nadávalo, protože stojíc v nějaké složce otevřeli jiný soubor a Solution Explorer uskočil někam hentam onam, takže pak museli pracně hledat původní složku na kterou se dívali.&lt;br /&gt;&lt;br /&gt;Softwareový bůh je vyslyšel a v novém Visual Studiu 2005 chování toto zrušil. Ale ajta: našli se mnozí tací, které bylo slyšeti oplakávajíc fíčury ztracené a nadávajíc, že se v Solution Exploreru neorientujavša, neboť neznají lokaci právě otevřeného souboru. Nutno ovšem podotknouti, že struktura projektů a složek kverulantů těchto připomíná často spíše First-In-Never-Out kompostík než pravé vývojářské pískoviště. A zmizlo jim také Output Window, které se dříve dralo na světlo boží při každé kompilaci.&lt;br /&gt;&lt;br /&gt;Dlouho, předlouho dumaly týmy expertů a vymýšleli řešení. Po několika desetiletích bloudění a usilovné práce přišli na tento postup:&lt;br /&gt;&lt;br /&gt;- Otevř sobě dialog "Tools" - "Options".&lt;br /&gt;- Ukaž rypákem krysy své na "Projects and Solutions" skupinu i stiskni levý čumák její.&lt;br /&gt;- Hřebíkem označ "Track Active Item in Solution Explorer" a "Show Output window when build starts".&lt;br /&gt;- Rypákem krysy své "OK" zamáčkni.&lt;br /&gt;&lt;br /&gt;A jak psáno jest tak se také stane.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-115866276467054335?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/J_NkBFyyDX4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/115866276467054335/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=115866276467054335&amp;isPopup=true" title="Počet komentářů: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/115866276467054335" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/115866276467054335" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/J_NkBFyyDX4/jak-retardovat-vs2005.html" title="Jak retardovat VS2005" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2006/09/jak-retardovat-vs2005.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-115813486685555476</id><published>2006-09-13T09:58:00.000+02:00</published><updated>2007-09-14T16:47:49.260+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ReSharper" /><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><title type="text">Jak ladit unit testy s ReSharperem</title><content type="html">Tak jsem si nedávno do svého VS2005 nainstaloval nový zpomalovač &lt;a href="http://www.jetbrains.com/resharper" target="_blank"&gt;ReSharper&lt;/a&gt; 2.0.1. Vypadá to moc chytře (někdy až moc - např. intellisense má VS lepší a daleko rychlejší), a v nové verzi je integrované spouštění unit testů. Když otevřete nějakou třídu s testama, vedle metod se objeví zelenožluté puntíky, kterými se dá jednoduše spustit nebo debuggovat unit test. Spouštění zafungovalo samo a bez problémů, jenže ladění ne a ne se rozběhnout. Pořád to místo unit test metody spouštělo celý projekt.&lt;br /&gt;&lt;br /&gt;Pokud máte podobný problém, zkuste ho vyřešit takhle:&lt;br /&gt;&lt;br /&gt;1. Pokud jste někdy laborovali s TestDriven.Net, zkontrolujte nastavení projektu. Otevřete Properties projektu obsahující test. Přejděte na záložku Debug. Ve skupině "Start Action" musí být vybráno "Start project" (někdy tam může být nastavený TestDriven). &lt;br /&gt;&lt;br /&gt;2. V menu "ReSharper – Options…" zobrazte "Unit Testing" (úplně dole) a ve skupině "Debugging Method" vyberte "Use the project being tested". Výchozí hodnota je při instalaci nastavena na "Use the current startup project", což je, dle mého skromného názoru, volovina.&lt;br /&gt;&lt;br /&gt;3. Pak už můžete spouštět testy kliknutím na zelenožlutý puntík vlevo od metody s atributem Test.&lt;br /&gt;&lt;br /&gt;Také můžete sledovat průběh spouštění testů spolu s podrobným výstupem v okně Unit Test Runner. Pokud nevyskočí samo, otevřete ho z menu "ReSharper - Windows - Unit Test Runner". Takže nepotřebujete NUnit GUI a nemusíte si pořizovat TestDriven.&lt;br /&gt;&lt;br /&gt;Jeden háček to ale má. Při každém testování R# změní v nastavení Solution výchozí startup projekt na právě testovaný projekt, takže pokud pak chcete normálně spustit aplikaci, musíte znovu nastavit výchozí projekt.&lt;br /&gt;&lt;br /&gt;UPDATE: Pokud máte ReSharper verze 2.5 nebo nižší, nebudete moci debuggovat projekty umístěné v nějaké Solution Folder. Ve verzi 3.0 už to funguje.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-115813486685555476?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/AskOyqkZxf8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/115813486685555476/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=115813486685555476&amp;isPopup=true" title="Počet komentářů: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/115813486685555476" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/115813486685555476" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/AskOyqkZxf8/jak-ladit-unit-testy-s-resharperem.html" title="Jak ladit unit testy s ReSharperem" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2006/09/jak-ladit-unit-testy-s-resharperem.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-115462661705143714</id><published>2006-08-03T19:17:00.000+02:00</published><updated>2007-04-16T13:02:01.302+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="XPath" /><title type="text">Jak rozšířit XPath o vlastní funkce?</title><content type="html">Že jazyky spojené s XML lze rozšiřovat, ví i můj jedenapůlroční synovec. Přidat si do XSLT šablony vlastní funkce je triviální prkotina a na netu existují tisíce návodů jak to udělat. Buď šoupnete funkci přímo do XSLT šablony do &lt;span style="font-family:courier new;color:#006600;"&gt;&amp;lt;ms:script&amp;gt; &lt;/span&gt;elementu, nebo přidáte objekt implementující kýžené funkce do &lt;span style="font-family:courier new;color:#006600;"&gt;XsltArgumentList&lt;/span&gt; objektu metodou &lt;span style="font-family:courier new;color:#006600;"&gt;AddExtensionObject&lt;/span&gt; (což je hezčí neboť to přímo nabádá k reuse). Takový přehled možností je &lt;a href="http://msdn.microsoft.com/msdnmag/issues/02/03/xml/" target="_blank"&gt;zde&lt;/a&gt;. Jenže s XPath je to o něco komplikovanější.&lt;br /&gt;&lt;br /&gt;Pokud voláte XPath dotazy nad nějakým XML dokumentem přímo z kódu, musíte na to jít úplně jinak. Zřejmě to není tak obvyklý scénář, protože jsem šťoural internet skrz naskrz a vůbec nebylo lehké přijít na nějakou stránku s návodem jak to udělat. Trvalo celkem dlouho než jsem objevil tohle: &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;324462" target="_blank"&gt;HOW TO: Implement and Use Custom Extension Functions When You Execute XPath Queries in Visual C# .NET&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Klíčový trik spočívá ve vytvoření vlastního XSLT kontextu, tedy třídy dědící od &lt;span style="font-family:courier new;color:#006600;"&gt;XsltContext&lt;/span&gt;. V ní předefinujete dvě metody: &lt;span style="font-family:courier new;color:#006600;"&gt;ResolveFunction&lt;/span&gt; a &lt;span style="font-family:courier new;color:#006600;"&gt;ResolveVariable&lt;/span&gt;. Když XPath parser narazí na něco, co vypadá jako funkce nebo proměnná kterou nezná, zavolá jednu z těchto metod a my máme šanci podstrčit mu vlastní implementaci. Řešení je to ale o něco složitější než u XSLT, protože musíte vrátit objekt implementující správné rozhraní - &lt;span style="font-family:courier new;color:#006600;"&gt;IXsltContextFunction&lt;/span&gt; nebo &lt;span style="font-family:courier new;color:#006600;"&gt;IXsltContextVariable&lt;/span&gt;. Ovšem s návodem už je to brnkačka, takže nemá cenu dál rozebírat detaily:-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-115462661705143714?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/7wk5fNEup_8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/115462661705143714/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=115462661705143714&amp;isPopup=true" title="Počet komentářů: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/115462661705143714" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/115462661705143714" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/7wk5fNEup_8/jak-rozit-xpath-o-vlastn-funkce.html" title="Jak rozšířit XPath o vlastní funkce?" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2006/08/jak-rozit-xpath-o-vlastn-funkce.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-115441640611627910</id><published>2006-08-01T09:00:00.000+02:00</published><updated>2007-04-16T12:59:34.568+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ViewState" /><title type="text">Jak zjistit celkovou velikost ViewState?</title><content type="html">Když si zapnete podrobné trasování běhu stránky pomocí elementu &lt;span class="code"&gt;&amp;lt;trace&amp;gt;&lt;/span&gt; v souboru web.config, ASP.NET vám do stránky vypíše strom ovládacích prvků a informaci o velikosti jejich ViewState a ControlState. Jaká je ale celková velikost dat odesílanýchve skrytém HTML poli __VIEWSTATE?&lt;br /&gt;&lt;br /&gt;Na internetu lze nalézt několik návodů, jak přidat informaci o velikosti ViewState do trace logu. Jenže všechny co jsem našel zjišťují velikost podle &lt;span style="font-family:courier new;color:#006600;"&gt;Request["__VIEWSTATE"]&lt;/span&gt;, ale to je navrácený ViewState, odeslaný z předchozí stránky! Pokud nás zajímá, kolik dat odesíláme ve ViewState aktuálně zpracovávané stránky, musíme použít daleko špinavější trik.&lt;br /&gt;&lt;br /&gt;Výchozí PageStatePersister stránky pro ViewState je &lt;span style="font-family:courier new;color:#006600;"&gt;HiddenFieldPageStatePersister&lt;/span&gt;, který v metodě &lt;span style="font-family:courier new;color:#006600;"&gt;Save()&lt;/span&gt; zkomprimuje ViewState a ControlState a vloží jej do interního textového pole &lt;span style="font-family:courier new;color:#006600;"&gt;ClientState&lt;/span&gt; stránky. Stránka jej pak později narenderuje do jednoho nebo více skrytých polí __VIEWSTATE (záleží na nastavení vlastnosti stránky MaxPageStateFieldLength). No a tak si zjistíme jak je toto pole dlouhé a přidáme to do trace logu:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;protected override void Render(HtmlTextWriter writer)&lt;br /&gt;{&lt;br /&gt;#if DEBUG&lt;br /&gt;    System.Reflection.PropertyInfo secretState =&lt;br /&gt;        this.GetType().GetProperty(&lt;br /&gt;            "ClientState",&lt;br /&gt;            System.Reflection.BindingFlags.Instance |&lt;br /&gt;            System.Reflection.BindingFlags.NonPublic&lt;br /&gt;        );&lt;br /&gt;    string viewState = (string)secretState.GetValue(this, null);&lt;br /&gt;    if (viewState != null)&lt;br /&gt;        Trace.Warn("ViewState Size", viewState.Length.ToString());&lt;br /&gt;    else&lt;br /&gt;        Trace.Warn("ViewState Size", "0");&lt;br /&gt;#endif&lt;br /&gt;    base.Render(writer);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;No a je to. Informace o velikosti ViewState je vidět přímo v trace logu stránky! Dobrý, ne? Reflexe interního pole je ovšem špinavá technika a jsou k ní potřeba určitá práva. Pro ladění stránek a velikosti ViewState je to však príma.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-115441640611627910?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/nmMtW0pnSqw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/115441640611627910/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=115441640611627910&amp;isPopup=true" title="Počet komentářů: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/115441640611627910" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/115441640611627910" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/nmMtW0pnSqw/jak-zjistit-celkovou-velikost.html" title="Jak zjistit celkovou velikost ViewState?" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2006/08/jak-zjistit-celkovou-velikost.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-25517922.post-114431004416587768</id><published>2006-04-06T09:53:00.000+02:00</published><updated>2006-04-06T09:54:04.166+02:00</updated><title type="text">Zkušební post</title><content type="html">Ali Baba programuje!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25517922-114431004416587768?l=www.kolman.cz%2Falibaba%2Fdefault.htm'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AliBabaProgramuje/~4/OPSuuQtqv2s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/114431004416587768/comments/default" title="Komentáře k příspěvku" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=25517922&amp;postID=114431004416587768&amp;isPopup=true" title="Počet komentářů: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/114431004416587768" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25517922/posts/default/114431004416587768" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AliBabaProgramuje/~3/OPSuuQtqv2s/zkuebn-post.html" title="Zkušební post" /><author><name>Ali Baba</name><uri>http://www.blogger.com/profile/12541334749939254340</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="00019423723998027543" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.kolman.cz/alibaba/2006/04/zkuebn-post.html</feedburner:origLink></entry></feed>

