<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Steves blog</title>
	<atom:link href="http://blog.stevesindelar.cz/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.stevesindelar.cz</link>
	<description>all you can eat</description>
	<lastBuildDate>Mon, 15 Aug 2011 22:02:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Vyúčtování.com</title>
		<link>http://blog.stevesindelar.cz/vyuctovani-com</link>
		<comments>http://blog.stevesindelar.cz/vyuctovani-com#comments</comments>
		<pubDate>Mon, 15 Aug 2011 22:02:06 +0000</pubDate>
		<dc:creator>Steves</dc:creator>
				<category><![CDATA[Nezařazené]]></category>

		<guid isPermaLink="false">http://blog.stevesindelar.cz/?p=435</guid>
		<description><![CDATA[Byli jsme takhle jednou na dvoutýdenním road-tripu po Skotsku a během něj jsme všichni střídavě platili různé společné výdaje: benzín, erární jídlo, mapy, parkování atd. Když jsme se pak vrátili domů bylo potřeba sepsat všechny účty, rozdělit výdaje a určit kdo kolik a komu dluží. V té době jsem si řekl, že by bylo fajn [...]]]></description>
			<content:encoded><![CDATA[<p>Byli jsme takhle jednou na dvoutýdenním road-tripu po Skotsku a během něj jsme všichni střídavě platili různé společné výdaje: benzín, erární jídlo, mapy, parkování atd. Když jsme se pak vrátili domů bylo potřeba sepsat všechny účty, rozdělit výdaje a určit kdo kolik a komu dluží. V té době jsem si řekl, že by bylo fajn mít online aplikaci, kam by všichni přidali účty, co platili, a ona by pak všechno spočítala. Deštivé léto si zatím moc neužívám, ale alespoň zbylo trochu času na to, abych to konečně naprogramoval, a říkal jsem si, že by se taková aplikace mohla hodit třeba i dalším: <a href="http://vyuctovani.com" title="Vyuctovani.com">vyuctovani.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stevesindelar.cz/vyuctovani-com/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>GraphViz pro .NET: generování &#8222;pěkných&#8220; grafů ve WPF</title>
		<link>http://blog.stevesindelar.cz/graphviz-pro-net-generovani-peknych-grafu-ve-wpf</link>
		<comments>http://blog.stevesindelar.cz/graphviz-pro-net-generovani-peknych-grafu-ve-wpf#comments</comments>
		<pubDate>Fri, 15 Jul 2011 09:26:05 +0000</pubDate>
		<dc:creator>Steves</dc:creator>
				<category><![CDATA[Nezařazené]]></category>
		<category><![CDATA[.net]]></category>

		<guid isPermaLink="false">http://blog.stevesindelar.cz/?p=425</guid>
		<description><![CDATA[GraphViz je software pro vizualizaci grafů. Může tedy sloužit například k &#8222;přehlednému&#8220; zobrazení grafu přátel na Facebooku. GraphViz jako takový poskytuje pouze program pro příkazovou řádku, pomocí kterého lze grafy generovat do různých grafických formátů nebo do textového formátu reprezentujícího informace o layoutu. Pokud bychom chtěli takový graf zobrazit ve WPF, můžeme použít komponentu Image, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.graphviz.org" title="Domací stránka GraphViz">GraphViz</a> je software pro vizualizaci grafů. Může tedy sloužit například k &#8222;přehlednému&#8220; zobrazení grafu přátel na Facebooku. GraphViz jako takový poskytuje pouze program pro příkazovou řádku, pomocí kterého lze grafy generovat do různých grafických formátů nebo do textového formátu reprezentujícího informace o layoutu. Pokud bychom chtěli takový graf zobrazit ve WPF, můžeme použít komponentu Image, ale co kdybychom chtěli, aby součástí vygenerovaného grafu byly i &#8222;živé&#8220; prvky, například klikatelné tlačítka, select boxy a podobně? V takovém případě je tu <a href="http://graphviz4net.codeplex.com/" title="Graphviz4Net na Codeplex">Graphviz4Net</a>, který umí zpracovat textový výstup GraphVizu a aplikovat informace o layoutu daného grafu na libovolné WPF komponenty.</p>
<p><span id="more-425"></span></p>
<p><img src="http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=graphviz4net&#038;DownloadId=259241" title="Ukázka použití Graphviz4Net" alt="Graf přátel vizualizovaný ve WPF pomocí Graphviz4Net"/></p>
<h2>Jak funguje GraphViz</h2>
<p>Samotný GraphViz (tedy nikoliv Graphviz4Net) se používá zhruba následovně. Stačí vytvořit textovou reprezentaci grafu, který chceme vizualizovat. K tomuto účelu slouží jazyk DOT.</p>
<pre class="brush: csharp">
digraph G {
	node [shape=rect];
	node1 [label="A", width=2, height=1];
	node2 [label="B"];
	node3; node5;
	node1 -> node2 [label="Edge from A to B"];
	node3 -> node1; node3 -> node5;
	node1 -> node5; node5 -> node2;
}
</pre>
<p>Potom stačí použít utilitu dot, která je součástí GraphViz.</p>
<pre class="brush: csharp">
dot -Tpng graph.gv > graph.png
</pre>
<p>A výsledný obrázek vypadá následovně:<br />
<img src="/wp-content/uploads/graph.png" title="Graf vygenerovaný GraphVizem" width="138" height="201" /></p>
<h2>Graphviz4Net</h2>
<p>Graphviz4Net umožňuje použít GraphViz pro vizualizaci grafů ve WPF. Uzly grafu mohou být libovolné WPF komponenty, i všechny další prvky grafu je možné customizovat. Graphviz4Net podporuje pod-grafy (ohraničené komponenty v grafu), hrany mezi pod-grafy, popisky u hran, popisky u konců hran a různé tvary konců hran. Více informací o Graphviz4Net, včetně příkladu použití, lze získat na domácí <a href="http://graphviz4net.codeplex.com/" title="Graphviz4Net na Codeplex">stránce projektu</a>.</p>
<p><img src="http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=graphviz4net&#038;DownloadId=259242" title="Další ukázka použití Graphviz4Net ve WPF" alt="Další ukázka použití Graphviz4Net ve WPF"/></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stevesindelar.cz/graphviz-pro-net-generovani-peknych-grafu-ve-wpf/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Návrhový vzor Visitor</title>
		<link>http://blog.stevesindelar.cz/navrhovy-vzor-visitor</link>
		<comments>http://blog.stevesindelar.cz/navrhovy-vzor-visitor#comments</comments>
		<pubDate>Thu, 23 Jun 2011 14:27:14 +0000</pubDate>
		<dc:creator>Steves</dc:creator>
				<category><![CDATA[Nezařazené]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[architektura]]></category>
		<category><![CDATA[kód]]></category>

		<guid isPermaLink="false">http://blog.stevesindelar.cz/?p=380</guid>
		<description><![CDATA[V tomto článku se podíváme na zoubek návrhovému vzoru Visitor a jeho implementaci v C# bez použití i s použitím Reflexe. Tento návrhový vzor patří k těm složitějším a kvůli svému ne úplně šťastně zvolenému názvu je často zdrojem nejasností i pro zkušenější programátory. Domnívám se, že problém často vězí v nepochopení účelu a motivace [...]]]></description>
			<content:encoded><![CDATA[<p>V tomto článku se podíváme na zoubek návrhovému vzoru Visitor a jeho implementaci v C# bez použití i s použitím Reflexe. Tento návrhový vzor patří k těm složitějším a kvůli svému ne úplně šťastně zvolenému názvu je často zdrojem nejasností i pro zkušenější programátory. Domnívám se, že problém často vězí v nepochopení účelu a motivace pro tento vzor, proto se na začátku článku zaměříme na tyto aspekty a pak až se podíváme na implementaci samotného vzoru.</p>
<p><span id="more-380"></span></p>
<h2>Methods dispatching</h2>
<p>Nejprve zavedeme jednoduchou terminologii &#8212; <em>statický typ</em> objektu a <em>aktuální typ</em> objektu. V následující ukázce je Stream statickým typem objektu &#8222;obj&#8220; a FileStream je jeho aktuálním typem. Aktuálním typem objektu &#8222;obj&#8220; může být kterýkoliv potomek abstraktní třídy Stream.</p>
<pre class="brush: csharp">
Stream obj = new FileStream("foo.txt", FileMode.Create);
// ... změníme aktuální typ:
obj = new MemoryStream(/* ... */);
</pre>
<p>Začneme menším kvízem: co bude výstupem následujícího program (nebo-li, která verze metody Foo se zavolá)?</p>
<pre class="brush: csharp">
public class Program {
  public static void Foo(object o) {
    Console.WriteLine("Foo:object");
  }

  public static void Foo(string str) {
    Console.WriteLine("Foo:string");
  }

  public static void Main(string[] args) {
    object obj = new string("ahoj svete");
    Foo(obj);
  }
}
</pre>
<p>Správná odpověď je &#8222;Foo:object&#8220;, protože kompilátor vybírá mezi Foo(string) a Foo(object) už během kompilace na základě <em>statického typu</em> parametru &#8222;obj&#8220; a tím je object, ne string. Jediný případ (zatím neuvažujeme Reflection), kdy je skutečně zavolaná metoda vybrána až za běhu, jsou virtuální metody jako u následujícího příkladu, jehož výstupem je &#8222;Foo:Bar&#8220;.</p>
<pre class="brush: csharp">
public class Program {
  class Baz {
    public virtual void Foo() {
      Console.WriteLine("Foo:Baz");
    }
  }

  class Bar : Baz {
    public override void Foo() {
      Console.WriteLine("Foo:Bar");
    }
  }

  public static void Main(string[] args) {
    Baz b = new Bar();
    b.Foo();
  }
}
</pre>
<p>Zde je metoda Foo vybraná na základě <em>aktuálního typu</em> objektu b, tedy je správně vybraná metoda Foo ze třídy Bar. Proč tomu tak je a jak to celé funguje? C# kód se překládá do mezikódu (MSIL) a tento mezikód potom překládá Just-in-time kompilátor přímo do strojového kódu. .NET mezikód je takový trochu &#8222;higher-level assembler&#8220; a poskytuje několik instrukcí pro volání metod. Nejdůležitější jsou .call a .callvirt. Čím se tyto dvě instrukce liší? První z nich, .call, překládá Just-in-time kompilátor čistě jako volání konkrétní metody pomocí její pevně zadané adresy. Na druhou stranu instrukce .callvirt je přeložena do strojového kódu, který adresu volané metody vybere podle tabulky virtuálních metod. Důsledkem je, že instrukce .callvirt je pomalejší než .call, ale poskytuje lepší flexibilitu. </p>
<p>Tomu jak se vybírá metoda, která je nakonec skutečně zavolaná, se říká dispatching od anglického dispatch (vypravit, expedovat). C# podporuje takzvaný single dispatch, kdy je skutečná metoda vybraná na základě <em>aktuálního typu</em> objektu, na kterém je zavolaná. Některé jazyky, především dynamické, podporují takzvaný multiple dispatch, kdy je skutečně zavolaná metoda vybraná na základě aktuálních typů všech jejích argumentů i objektu, na kterém je zavolaná (pokud je instanční). Kód ekvivalentní úvodní ukázce by v takovém jazyce po spuštění vypsal &#8222;Foo:string&#8220;. </p>
<p>Multiple dispatch lze použít i v C# pomocí klíčového slova dynamic. Následující kód vypíše &#8222;Foo:string&#8220;. Důležité je přetypování parametru na &#8222;dynamic&#8220;.</p>
<pre class="brush: csharp">
public class Program {
  public static void Foo(object o) {
    Console.WriteLine("Foo:object");
  }

  public static void Foo(string str) {
    Console.WriteLine("Foo:string");
  }

  public static void Main(string[] args) {
    object obj = new string("ahoj svete");
    Foo((dynamic)obj);
  }
}
</pre>
<h2>K čemu se hodí multiple dispatch?</h2>
<p>Uvažme následující hierarchii tříd</p>
<pre class="brush: csharp">
public class Employee {
  double Salary { get; set; }
}

public class Worker : Employee {}
public class Manager : Employee {}
</pre>
<p>a nyní následující situaci: máme instanci kolekce objektů typu Employee a chceme všem managerům (třída Manager) zvýšit plat o 1000 a pracovníkům (třída Worker) snížit o 500. Méně zkušený vývojář by v takovém případě možná napsal následující kód:</p>
<pre class="brush: csharp">
public void Foo(IEnumerable&lt;Employee&gt; employees) {
  foreach(var e in employees) {
    if (e is Manager) {
      e.Salary += 1000;
    } else {
      e.Salary -= 500;
    }
  }
}
</pre>
<p>Takový &#8222;if&#8220; je přesně věc, která by se v pořádném OOP návrhu neměla objevit a tento kód přímo volá po použití virtuální metody. Problém je ale v tom, že jednou budeme chtít přidávat/ubírat peníze, jednou zase něco úplně jiného a ve výsledku bude třída Employee plná nekonzistentních virtuálních metod. (Puristé v tom už vidí poručení Open/Closed principu.) Nyní přichází na řadu multiple dispatch, přesněji double dispatch, protože budeme chtít vybírat metodu na základě <em>aktuálního typu</em> prvního parametru.</p>
<pre class="brush: csharp">
class ChangeSalary {
  public void Visit(Manager m) { m.Salary += 1000; }
  public void Visit(Worker m) { m.Salary -= 500; }
}
// ...
public void Foo(IEnumerable&lt;Employee&gt; employees) {
  var visitor = new ChangeSalary();
  foreach(var e in employees) {
    visitor.Visit((dynamic)e);
  }
}
</pre>
<p>Nyní můžeme snadno přidávat a odebírat různé další třídy podobné ChangeSalary, není třeba upravovat kód v třídě Employee a zbavili jsme se nechtěného ifu. Výše uvedený kód je v podstatě implementace návrhového vzoru Visitor, ovšem díky podpoře pro double dispatch přes dynamic je skutečně jednoduchá. Někteří vývojáři zastávají názor, že se v takovém případě už ani nedá mluvit o návrhovém vzoru, prostě jazyky, které podporují double dispatch, podle nich návrhový vzor Visitor nepotřebují. Lze se na to dívat i tak, že ačkoliv je implementace vzoru Visitor v tomto případě velmi jednoduchá, pořád za ní stojí základní myšlenka tohoto vzoru &#8212; odstranění příkazů if nebo switch, které testují aktuální typu objektu.</p>
<p>Co je tedy na vzoru Visitor tak složitého? Na to se podíváme v následující sekci.</p>
<h2>Visitor bez double dispatch</h2>
<p>Některé jazyky vůbec nepodporují double dispatch, například C++, a v některých jazycích použití double dispatch znamená drobné snížení výkonnosti (pamatujete na rozdíl mezi .call a .callvirt, v tomto případě je rozdíl ještě větší). Jak tedy implementovat double dispatch, když pro něj nemáme přímou podporu? Odpovědí je dvojité použití virtuálních metod. Následuje ukázka takové implementace a její popis.</p>
<pre class="brush: csharp">
abstract class Visitor {
  public virtual void Visit(Manager m) {}
  public virtual void Visit(Worker w) {}
}

abstract class Employee {
  public abstract void Accept(Visitor v);
}

class Manager : Employee {
  public override void Accept(Visitor v) {
    v.Visit(this);
  }
}

class Worker : Employee {
  public override void Accept(Visitor v) {
    v.Visit(this);
  }
}

class ChangeSalary : Visitor {
  public override void Visit(Manager m) {
    m.Salary += 1000;
  }
  public override void Visit(Worker w) {
    w.Salary -= 500;
  }
}

//...
var visitor = new ChangeSalary();
foreach(var e in employees) {
  e.Accept(visitor);
}
</pre>
<p>Pomocí virtuální metody Accept ve třídě Employee zjistíme <em>aktuální typ</em> objektů, které mají <em>statický typ</em> Employee &#8212; to znamená že je potřeba tuto metodu překrýt v každém potomkovi třídy Employee. Metoda Accept dostane instanci třídy Visitor, zavolá na ní další virtuální metodu Visit a jako parametr předá this. V tuhle chvíli má this správný statický typ, protože pomocí mechanizmu virtuálních metoda byla zavolaná metoda Accept na nějakém potomkovi Employee. Tohle už je trochu složitější. Důležité je, že pomocí uvedených tříd a metod se snažíme dosáhnout něčeho jako double dispatch. To je hlavní podstata návrhového vzoru Visitor.</p>
<p>Uvedený kód může být i názornou ukázkou, že správný vývojář by měl používat adekvátní postupy a metody. Počet řádků oproti původní verzi bez vzoru Visitor značně narostl. Přidali jsme nové třídy a virtuální metody, které je potřeba správně překrývat, i když kompilátor to nijak nevynucuje! Z pohledu našeho jednoduchého příkladu se původní kód proměnil v poměrně komplexní soustavu tříd zajišťující netriviální funkcionalitu (double dispatch) a přínos vzoru není tak úplně vidět. </p>
<p>Je tedy důležité podotknout, že návrhový vzor Visitor je doporučeno použít v situaci, kdy </p>
<ul>
<li>důležitost, rozsah a životnost projektu si vyžaduje použití tak komplexních řešení jako je návrhový vzor Visitor. Ještě horší než nerozumět návrhovým vzorům, je snažit se je aplikovat všude a bez rozmyslu.</li>
<li>&#8222;Navštěnovanou&#8220; hierarchii (Employee-Manager-Worker) tvoří spíše stabilní třídy, jejichž kód se často nemění a celkově do dané hierarchie nejsou často přidávány nové třídy.</li>
<li>Operace na hierarchií, které jsou vlastně implementacemi třídy Visitor, často přibývají/ubývají.</li>
</ul>
<p>Stejně jako většina ostatních postupů, kterými se typicky dosahuje zachování principu Open/Closed, porušuje návrhový vzor Visitor princip zapouzdření, protože &#8222;navštěvované&#8220; objekty musí poskytovat veřejné vlastnosti (properties) a další metody, které jednotlivé implementace třídy Visitor potřebují, aby odvedly svoji práci.  </p>
<h2>Kde je to navštěvování?</h2>
<p>Návrhový vzor Visitor podle svého názvu může evokovat představu, že jeho podstatou je rekurzivní navštěvování hierarchie tříd, jako v následující ukázce.</p>
<pre class="brush: csharp">
abstract class Visitor {
  public virtual void Visit(Layout layout) {}
  public virtual void Visit(Label label) {}
}

abstract class VisualElement {
  public abstract void Accept(Visitor v);
}

class Layout : VisualElement {
  private IList&lt;VisualElement&gt; children;
  //...**Důležitá část:**
  public override void Accept(Visitor v) {
    v.Visit(this);
    foreach(var c in this.children) {
      c.Accept(v);
    }
  }
}

class Label : VisualElement {
  public override void Accept(Visitor v) {
    v.Visit(this);
  }
}

class CountElements : Visitor {
  int layouts = 0;
  int labels = 0;
  public override void Visit(Layout layout) {
    this.layouts++;
  }
  public override void Visit(Label label) {
    this.labels++;
  }
}

//...
var visitor = new CountElements();
foreach(var e in visualElements) {
  e.Accept(visitor);
}
</pre>
<p>Ovšem kód, kde objekt typu Layout volá metodu Accept na agregovaných widgetech, není esenciální součástí vzoru Visitor, ale spíš ukázka kompozice vzoru Visitor a Composite (velmi často používaná varianta). V bibli návrhových vzorů &#8222;Gang of Four&#8220; se můžeme dočíst, že procházení kolekce nebo hierarchie &#8222;navštěvovaných&#8220; objektů může být realizováno v těchto objektech právě pomocí vzoru Composite, v samotné třídě Visitor nebo dokonce může být celé ponecháno na klientech.</p>
<h2>Závěr</h2>
<p>Návrhový vzor Visitor nám umožní implementovat double dispatch v jazycích, kde buďto není vůbec podporovaný, nebo jeho použití přináší určitý dopad na výkonnost. Díky double dispatch potom není třeba vytvářet konstrukce typu switch nebo zřetězené příkazy if-else-if, které testují <em>aktuální typ</em> objektu, což je obtížně rozšiřitelný a spravovatelný kód. Pokud povaha našeho programu povoluje použití klíčového slova dynamic, i přes nepatrné snížení výkonu, je vhodné jej použít pro implementaci double dispatch a zjednodušit tak výsledný kód; návrhový vzor Visitor se v takovém případě z kódu téměř vytrácí.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stevesindelar.cz/navrhovy-vzor-visitor/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mono.Cecil: How to get all base types and interfaces with resolved generic arguments</title>
		<link>http://blog.stevesindelar.cz/mono-cecil-how-to-get-all-base-types-and-interfaces-with-resolved-generic-arguments</link>
		<comments>http://blog.stevesindelar.cz/mono-cecil-how-to-get-all-base-types-and-interfaces-with-resolved-generic-arguments#comments</comments>
		<pubDate>Thu, 05 May 2011 17:32:21 +0000</pubDate>
		<dc:creator>Steves</dc:creator>
				<category><![CDATA[Nezařazené]]></category>

		<guid isPermaLink="false">http://blog.stevesindelar.cz/?p=370</guid>
		<description><![CDATA[Following code is the result of a discussion in the mono-cecil user group. If you don&#8217;t know what Mono.Cecil is, this post probably does not contain much information for you. However, you could check out this great library and maybe come back later. 

Limitations

At the moment it does not resolve generic arguments recursively, so for [...]]]></description>
			<content:encoded><![CDATA[<p>Following code is the result of a <a href="http://groups.google.com/group/mono-cecil/browse_thread/thread/bedb76e4afbcb45b">discussion</a> in the <a href="http://groups.google.com/group/mono-cecil">mono-cecil</a> user group. If you don&#8217;t know what Mono.Cecil is, this post probably does not contain much information for you. However, you could check out this <a href="https://github.com/jbevain/cecil">great library</a> and maybe come back later. </p>
<p><span id="more-370"></span></p>
<h2>Limitations</h2>
<p>
At the moment it does not resolve generic arguments recursively, so for IDictionrary&lt;string, int&gt; it will return also  IEnumerable&lt;KeyValuePair&lt;TKey, TValue&gt;&gt; instead of correct IEnumerable&lt;KeyValuePair&lt;string, int&gt;&gt;.
</p>
<h2>Disclaimer</h2>
<p>
I admin that the code is not as nice as it should be and it definitely contains some nasty bugs, which will appear under some esoteric circumstances, however on coming deadline is pushing me to do a few technical debts. Despite that I think some other people might find it helpful, at least as a starting point to their own implementation.
</p>
<p>
<em>I would also like to thank to Jb Evains for creating and maintaining Cecil.</em>
</p>
<pre class="brush: csharp">
        public static IEnumerable&lt;TypeReference&gt; GetBaseTypes(
			this TypeDefinition type,
			bool includeIfaces)
        {
            Contract.Requires(type != null);
            Contract.Requires(
				type.IsInterface == false,
				"GetBaseTypes is not valid for interfaces");

            var result = new List&lt;TypeReference&gt;();
            var current = type;
            var mappedFromSuperType = new List&lt;TypeReference&gt;();
            var previousGenericArgsMap =
				GetGenericArgsMap(
					type,
					new Dictionary&lt;string, TypeReference&gt;(),
					mappedFromSuperType);
            Contract.Assert(mappedFromSuperType.Count == 0);

            do
            {
                var currentBase = current.BaseType;
                if (currentBase is GenericInstanceType)
                {
                    previousGenericArgsMap =
							GetGenericArgsMap(
								current.BaseType,
								previousGenericArgsMap,
								mappedFromSuperType);
                    if (mappedFromSuperType.Any())
                    {
                        currentBase = ((GenericInstanceType)currentBase)
							.ElementType.MakeGenericInstanceType(
								previousGenericArgsMap
									.Select(x =&gt; x.Value)
									.ToArray());
                        mappedFromSuperType.Clear();
                    }
                }
                else
                {
                    previousGenericArgsMap =
						new Dictionary&lt;string, TypeReference&gt;();
                }

                result.Add(currentBase);
                current = current.BaseType.SafeResolve(
                    string.Format(
						CannotResolveMessage,
						current.BaseType.FullName,
						current.FullName));
                if (includeIfaces)
                {
                    result.AddRange(BuildIFaces(current, previousGenericArgsMap));
                }
            }
            while (current.IsEqual(typeof(object)) == false);

            return result;
        }

        private static IEnumerable&lt;TypeReference&gt; BuildIFaces(
			TypeDefinition type,
			IDictionary&lt;string, TypeReference&gt; genericArgsMap)
        {
            var mappedFromSuperType = new List&lt;TypeReference&gt;();
            foreach (var iface in type.Interfaces)
            {
                var result = iface;
                if (iface is GenericInstanceType)
                {
                    var map =
						GetGenericArgsMap(
							iface,
							genericArgsMap,
							mappedFromSuperType);
                    if (mappedFromSuperType.Any())
                    {
                        result = ((GenericInstanceType)iface).ElementType
                            .MakeGenericInstanceType(
								map.Select(x =&gt; x.Value).ToArray());
                    }
                }

                yield return result;
            }
        }

        private static IDictionary&lt;string, TypeReference&gt; GetGenericArgsMap(
            TypeReference type,
            IDictionary&lt;string, TypeReference&gt; superTypeMap,
            IList&lt;TypeReference&gt; mappedFromSuperType)
        {
            var result = new Dictionary&lt;string, TypeReference&gt;();
            if (type is GenericInstanceType == false)
            {
                return result;
            }

            var genericArgs = ((GenericInstanceType)type).GenericArguments;
            var genericPars = ((GenericInstanceType)type)
				.ElementType.SafeResolve(CannotResolveMessage).GenericParameters;

            /*
             * Now genericArgs contain concrete arguments for the generic
			 * parameters (genericPars).
             *
             * However, these concrete arguments don't necessarily have
			 * to be concrete TypeReferences, these may be referencec to
			 * generic parameters from super type.
             *
             * Example:
             *
             *      Consider following hierarchy:
             *          StringMap&lt;T&gt; : Dictionary&lt;string, T&gt;
             *
             *          StringIntMap : StringMap&lt;int&gt;
             *
             *      What would happen if we walk up the hierarchy from StringIntMap:
             *          -&gt; StringIntMap
             *              - here dont have any generic agrs or params for StringIntMap.
             *              - but when we reesolve StringIntMap we get a
			 *					reference to the base class StringMap&lt;int&gt;,
             *          -&gt; StringMap&lt;int&gt;
             *              - this reference will have one generic argument
			 *					System.Int32 and it's ElementType,
             *                which is StringMap&lt;T&gt;, has one generic argument 'T'.
             *              - therefore we need to remember mapping T to System.Int32
             *              - when we resolve this class we'll get StringMap&lt;T&gt; and it's base
             *              will be reference to Dictionary&lt;string, T&gt;
             *          -&gt; Dictionary&lt;string, T&gt;
             *              - now *genericArgs* will be System.String and 'T'
             *              - genericPars will be TKey and TValue from Dictionary
			 * 					declaration Dictionary&lt;TKey, TValue&gt;
             *              - we know that TKey is System.String and...
             *              - because we have remembered a mapping from T to
			 *					System.Int32 and now we see a mapping from TValue to T,
             *              	we know that TValue is System.Int32, which bring us to
			 *					conclusion that StringIntMap is instance of
             *          -&gt; Dictionary&lt;string, int&gt;
             */              

            for (int i = 0; i &lt; genericArgs.Count; i++)
            {
                var arg = genericArgs[i];
                var param = genericPars[i];
                if (arg is GenericParameter)
                {
                    TypeReference mapping;
                    if (superTypeMap.TryGetValue(arg.Name, out mapping) == false)
                    {
                        throw new Exception(
                            string.Format(
                                "GetGenericArgsMap: A mapping from supertype was not found. " +
                                "Program searched for generic argument of name {0} in supertype generic arguments map " +
                                "as it should server as value form generic argument for generic parameter {1} in the type {2}",
                                arg.Name,
                                param.Name,
                                type.FullName));
                    }

                    mappedFromSuperType.Add(mapping);
                    result.Add(param.Name, mapping);
                }
                else
                {
                    result.Add(param.Name, arg);
                }
            }

            return result;
        }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.stevesindelar.cz/mono-cecil-how-to-get-all-base-types-and-interfaces-with-resolved-generic-arguments/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Seriál o Code Contracts na programujte.com</title>
		<link>http://blog.stevesindelar.cz/serial-o-code-contracts</link>
		<comments>http://blog.stevesindelar.cz/serial-o-code-contracts#comments</comments>
		<pubDate>Wed, 23 Feb 2011 20:28:36 +0000</pubDate>
		<dc:creator>Steves</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[.net]]></category>

		<guid isPermaLink="false">http://blog.stevesindelar.cz/?p=367</guid>
		<description><![CDATA[Před pár dny vyšel na portálu programujte.com úvodní díl mého seriálu o Code Contracts.
]]></description>
			<content:encoded><![CDATA[<p>Před pár dny vyšel na portálu programujte.com <a href="http://programujte.com/?akce=clanek&#038;cl=2011021200-code-contracts-uvod" title="Seriál o Code Contracts na programujte.com">úvodní díl</a> mého seriálu o Code Contracts.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stevesindelar.cz/serial-o-code-contracts/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enterprise Library: konfigurace ve více souborech</title>
		<link>http://blog.stevesindelar.cz/entlib-konfigurace-ve-vice-souborech</link>
		<comments>http://blog.stevesindelar.cz/entlib-konfigurace-ve-vice-souborech#comments</comments>
		<pubDate>Sat, 04 Dec 2010 16:40:59 +0000</pubDate>
		<dc:creator>Steves</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[.net]]></category>

		<guid isPermaLink="false">http://blog.stevesindelar.cz/?p=325</guid>
		<description><![CDATA[V enterprise aplikacích je třeba postarat se o věci jako je logování, robustní zracování výjimek nebo o nastavení IoC kontejneru. Pokud nechcete psát kompletně vlastní infrastrukturu pro tyto účely, nabízí se MS Enterprise Library.
Entlib, jak se její jméno obvykle zkracuje, uchovává konfiguraci hlavně v xml souborech a to především v App.config případně Web.config. Konfigurace Entlib [...]]]></description>
			<content:encoded><![CDATA[<p>V enterprise aplikacích je třeba postarat se o věci jako je logování, robustní zracování výjimek nebo o nastavení <a title="Buzzwords okolo dependency injection: např. IoC." href="http://blog.stevesindelar.cz/buzz-words-okolo-dependency-injection">IoC kontejneru</a>. Pokud nechcete psát kompletně vlastní infrastrukturu pro tyto účely, nabízí se <a title="domovská stránka Entlib" href="http://msdn.microsoft.com/en-us/library/ff632023.aspx">MS Enterprise Library</a>.</p>
<p>Entlib, jak se její jméno obvykle zkracuje, uchovává konfiguraci hlavně v xml souborech a to především v App.config případně Web.config. Konfigurace Entlib může být pěkně rozsáhlá a orientovat se v jednom obrovském xml souboru, to nemusí být jednoduché. Nehledě na typické problémy se systémem správy verzí (svn/mercurial/git/&#8230;) V následujícím obrázkovém návodu ukážu jak nastavit Entlib tak, aby konfiguraci brala z více souborů.</p>
<p><span id="more-325"></span></p>
<p>Budu předpokládat, že Entlib už je nainstalovaná a potřebné sestavy (assembly) jsou nareferencované. Použijeme grafický konfigurační nástroj, odpovídající akce by bylo možné provést i ruční editací xml souborů.</p>
<p><img src="/wp-content/uploads/entlib1.png" alt="Pravý klik na web.config - v menu vybrat Edit Enterprise Library V5" width="463" height="324" /></p>
<p><img src="/wp-content/uploads/entlib2.png" alt="V menu Blocks - Add Configuration Block" width="395" height="453" /></p>
<p><img src="/wp-content/uploads/entlib3.png" alt="" width="759" height="246" /></p>
<p><img src="/wp-content/uploads/entlib4.png" alt="" width="566" height="266" /></p>
<p>Mohlo by se zdát, že tím je vše hotové, ale pozor. Ještě je třeba Entlib říct, co bude další konfigurační soubor obsahovat &#8212; jaké bloky budou nakonfigurovány v něm. Konfiguraci ostatních bloků bude Entlib stále brát z App.config resp. Web.config.</p>
<p><img src="/wp-content/uploads/entlib5.png" alt="" width="830" height="252" /></p>
<p><img src="/wp-content/uploads/entlib6.png" alt="" width="589" height="262" /></p>
<p>Jak má vypadat formát souboru entlibconfig.xml? Úplně stejně jako App.config nebo Web.config. Tady je ukázka souboru, který obsahuje pouze konfiguraci logovacího bloku. Tento soubor můžete editovat pomocí grafické utility úplně stejně jako Web.config.</p>
<pre class="brush: xml">
&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;configuration&gt;
    &lt;configSections&gt;
    &lt;section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" /&gt;
    &lt;/configSections&gt;
&lt;loggingConfiguration name="Logging Application Block" tracingEnabled="true"
    defaultCategory="General" logWarningsWhenNoCategoriesMatch="true"&gt;
    &lt;listeners&gt;
      &lt;add name="Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        fileName="trace.log" formatter="Text Formatter" /&gt;
    &lt;/listeners&gt;
    &lt;formatters&gt;
      &lt;add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        template="Timestamp: {timestamp}{newline}&amp;#xA;Message: {message}{newline}&amp;#xA;Category: {category}{newline}&amp;#xA;Priority: {priority}{newline}&amp;#xA;EventId: {eventid}{newline}&amp;#xA;Severity: {severity}{newline}&amp;#xA;Title:{title}{newline}"
        name="Text Formatter" /&gt;
    &lt;/formatters&gt;
    &lt;categorySources&gt;
      &lt;add switchValue="All" name="General"&gt;
        &lt;listeners&gt;
          &lt;add name="Flat File Trace Listener" /&gt;
        &lt;/listeners&gt;
      &lt;/add&gt;
    &lt;/categorySources&gt;
    &lt;specialSources&gt;
      &lt;allEvents switchValue="All" name="All Events" /&gt;
      &lt;notProcessed switchValue="All" name="Unprocessed Category" /&gt;
      &lt;errors switchValue="All" name="Logging Errors &amp;amp; Warnings"&gt;
        &lt;listeners&gt;
          &lt;add name="Flat File Trace Listener" /&gt;
        &lt;/listeners&gt;
      &lt;/errors&gt;
    &lt;/specialSources&gt;
  &lt;/loggingConfiguration&gt;
&lt;/configuration&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.stevesindelar.cz/entlib-konfigurace-ve-vice-souborech/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kontrakty a unit testy</title>
		<link>http://blog.stevesindelar.cz/kontrakty-a-unit-testy</link>
		<comments>http://blog.stevesindelar.cz/kontrakty-a-unit-testy#comments</comments>
		<pubDate>Fri, 15 Oct 2010 19:44:35 +0000</pubDate>
		<dc:creator>Steves</dc:creator>
				<category><![CDATA[Nezařazené]]></category>

		<guid isPermaLink="false">http://blog.stevesindelar.cz/?p=305</guid>
		<description><![CDATA[Jak se změní svět unit testování, když začneme používat kontrakty?

Pokud to myslíte s unit testy, potažmo TDD, opravdu velmi vážně, pak by pro vás neměla být následující ukázka překvapivá.

    public class Rectangle
    {
        public Rectangle(int width, int height)
     [...]]]></description>
			<content:encoded><![CDATA[<p>Jak se změní svět unit testování, když začneme používat kontrakty?</p>
<p><span id="more-305"></span></p>
<p>Pokud to myslíte s unit testy, potažmo TDD, opravdu velmi vážně, pak by pro vás neměla být následující ukázka překvapivá.</p>
<pre class="brush: csharp">
    public class Rectangle
    {
        public Rectangle(int width, int height)
        {
            this.Width = width;
            this.Height = height;
        }

        public int Width { get; private set; }
        public int Height { get; private set; }
    }	

	[TestFixture]
	public class RectangeTest
	{
		[Test]
		public void Fields_Of_Rectangle_Are_Assigned()
		{
			var r = new Rectangle(3, 4);
			Assert.AreEqual(3, r.Width);
			Assert.AreEqual(4, r.Height);
		}
	}
</pre>
<p>I ve dvou přiřazeních v konstruktoru se dá teoreticky udělat chyba, třeba je někdo může omylem prohodit. Podívejte se ale pozorně na výše uvedený test. Přijde vám na něm něco zvláštního? Napsat takový test je naprosto rutinní záležitost, možná bychom měli přenechat dřinu strojům&#8230;</p>
<h2>Kontrakty na scénu</h2>
<p>Výsledkem volání uvedeného konstruktoru, není nic, co by se nedalo popsat jednoduchou podmínkou. Oproti tomu, pokud máme implementovat metodu, co má v zadaném grafu najít nejkratší cestu, těžko popíšeme výsledek vzhledem k vstupním datům, to bychom museli pro ověření správnosti výsledku výsledek znovu vypočítat &#8212; nebo-li definice kruhem. Zpět k obdélníku. Podívejme se na verzi s kontrakty pro post-condition (=podmínky, co mají platit po provedení metody).</p>
<pre class="brush: csharp">
    public class Rectangle
    {
        public Rectangle(int width, int height)
        {
            Contract.Ensures(this.Width == width);
            Contract.Ensures(this.Height == height);

            this.Width = width;
            this.Height = height;
        }

         // ...
    }
</pre>
<p>V podstatě jsme zapsali to samé, co v unit testu, ale přehledněji, čistě deklarativně a v kódu &#8222;testované&#8220; třídy. Nicméně, v této verzi unit test chybí. Může tohle standardní milovník TDD akceptovat, aniž by autorovi tohoto kódu vyhlásil džihád? Odpověď je ano, může! Pokud máte nainstalované Code Contracts, zkuste prohodit width a height v přiřazovacích příkazech. Statická kontrola vám po kompilaci ihned ukáže chybu, protože za nás v podstatě udělala ten nudný unit-test z úvodu. Dokonce víc. Code Contracts provedly (logický) důkaz, že kód je správně. Takže nechme dřinu strojům a soustřeďme se na testování opravdu složitého kódu, který nelze ověřit statickou analýzou, třeba to hledání nejkratší cesty v grafu.</p>
<p>Co si myslíte o nahrazení unit-testů odpovídajícími kontrakty vy?</p>
<p><strong>Disclaimer</strong>: Code Contracts mají v současné verzi svoje mouchy. Syntaxe by taky mohla být hezčí. Prodloužená doba kompilace při použití Contracts se nemusí líbit každému. Ano unit-testování přiřazovacích příkazů, stejně jako psaní post-conditions pro jejich ověření, se může někomu jevit jako zbytečnost. <img src='http://blog.stevesindelar.cz/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stevesindelar.cz/kontrakty-a-unit-testy/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pokročilejší regulární výrazy v .NET</title>
		<link>http://blog.stevesindelar.cz/pokrocilejsi-regularni-vyrazy-v-net-2</link>
		<comments>http://blog.stevesindelar.cz/pokrocilejsi-regularni-vyrazy-v-net-2#comments</comments>
		<pubDate>Mon, 11 Oct 2010 16:39:35 +0000</pubDate>
		<dc:creator>Steves</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[.net]]></category>

		<guid isPermaLink="false">http://blog.stevesindelar.cz/?p=298</guid>
		<description><![CDATA[Pokud jste se někdy setkali s regulárními výrazy v souvislosti s vyhledáním a nahrazením, pak jste pravděpodobně přišli do styku i s pojmenovanými skupinami (named capturing groups). Jak už to bývá syntaxe v tomto směru není jednotná, a proto jsem si připravil pár příkladů na využití této featury v .NET.

Nahrazení *textu v hvězdičkách* za &#60;b&#62;textu [...]]]></description>
			<content:encoded><![CDATA[<p>Pokud jste se někdy setkali s regulárními výrazy v souvislosti s vyhledáním a nahrazením, pak jste pravděpodobně přišli do styku i s pojmenovanými skupinami (named capturing groups). Jak už to bývá syntaxe v tomto směru není jednotná, a proto jsem si připravil pár příkladů na využití této featury v .NET.</p>
<p><span id="more-298"></span></p>
<p>Nahrazení *textu v hvězdičkách* za &lt;b&gt;textu v hvězdičkách&lt;/b&gt;</p>
<pre class="brush: csharp">
Regex.Replace(sourceString, @"\*(?&lt;bold&gt;[^\*]*)\*", @"&lt;b&gt;${bold}&lt;/b&gt;");
</pre>
<p>Pojmenovaná skupina začíná závorkou, otazníkem a jménem skupiny ohraničeného většítkem a menšítkem, dále pokračuje tělo skupiny &#8212; tedy regulární výraz, který bude zachycovat znaky, co ještě &#8222;patří do skupiny&#8220; &#8212; a končí závorkou. Při nahrazování (případně jiných operacích) se lze na obsah pojmenované skupiny odvolat pomocí syntaxe ${jmenoSkupiny}.</p>
<p>Zkuste si představit, že všechny texty určené pro uživatele získáváte pomocí volání metody Translate(&#8222;idPrekladu&#8220;) a chcete získat všechny parametry, se kterými je tato metoda zavolána.</p>
<pre class="brush: csharp">
var matches = Regex.Matches(
     File.ReadAllText("soubor.cs"),
     @"Translate\(""(?&lt;id&gt;[^""]*)""\)");

foreach (Match match in matches)
{
    Console.WriteLine(match.Result("${id}"));
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.stevesindelar.cz/pokrocilejsi-regularni-vyrazy-v-net-2/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Customizace buildu ve VS &#8212; automatické spuštění unit testů</title>
		<link>http://blog.stevesindelar.cz/customizace-buildu-ve-vs-automaticke-spusteni-unit-testu</link>
		<comments>http://blog.stevesindelar.cz/customizace-buildu-ve-vs-automaticke-spusteni-unit-testu#comments</comments>
		<pubDate>Sun, 10 Oct 2010 19:44:09 +0000</pubDate>
		<dc:creator>Steves</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[architektura]]></category>

		<guid isPermaLink="false">http://blog.stevesindelar.cz/?p=255</guid>
		<description><![CDATA[Kompilátor nám u staticky typovaných jazyků pomůže odhalit spoustu chyb už při tzv. compile time, nebo-li když ve Visual Studiu stiskneme známou klávesovou zkratku CTRL+SHIFT+B. Kdo se nespokojí pouze s kontrolou typů a chce psát spolehlivější software, kromě kompilátoru užívá automatizovaných testů, především unit-testů. V tomto smyslu by se unit-testy daly chápat jako nadstavba kontroly [...]]]></description>
			<content:encoded><![CDATA[<p>Kompilátor nám u staticky typovaných jazyků pomůže odhalit spoustu chyb už při tzv. compile time, nebo-li když ve Visual Studiu stiskneme známou klávesovou zkratku CTRL+SHIFT+B. Kdo se nespokojí pouze s kontrolou typů a chce psát spolehlivější software, kromě kompilátoru užívá automatizovaných testů, především unit-testů. V tomto smyslu by se unit-testy daly chápat jako nadstavba kontroly kompilátorem, tak proč je také nespouštět hned po každé kompilaci? (Mimochodem uvědomme si, že unit-testy by měly být z definice rychlé, takže by jejich běh kompilaci neměl tolik zdržet.)</p>
<p><span id="more-255"></span></p>
<p>Jistě znáte soubory s příponou vcproj, případně vbproj pro Visual Basic. Jsou to projekty pro Visual Studio, takže je, přirozeně, otevíráte ve Visual Studiu, ale zkusili jste je někdy otevřít v obyčejném textovém editoru? Pokud byste tak učinili, uviděli byste něco podobného jako v následující ukázce: </p>
<pre class="brush: csharp">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://..."&gt;
  &lt;PropertyGroup&gt;
    &lt;Configuration Condition=" '$(Configuration)' == '' "&gt;Debug&lt;/Configuration&gt;
    &lt;Platform Condition=" '$(Platform)' == '' "&gt;AnyCPU&lt;/Platform&gt;
    &lt;!-- a tak dále ... --&gt;
</pre>
<p>už podle první řádky je jasné, že se jedná o xml. Konkrétně je to xml dialect určený pro MSBuild. Tento program, který naleznete na cestě &#8222;C:\Windows\Microsoft.NET\Framework\{verzeNET}\MSBuild.exe&#8220;, je interpretem speciálního deklarativního na xml postaveného jazyka. Podrobnou syntaxi naleznete v jiných článcích na internetu, pro účely spuštění unit testů po buildu si vysvětlíme nutné základy.</p>
<p>Formát MSBuild umožňuje definovat tzv. cíle (target). Atribut DefaultTargets kořenového uzlu Project určuje cíl, který bude defaultně spuštěn. Cíl může spouštět další cíle a úkoly (task). Význam úkolů si objasníme později. Kromě úkolů a cílů můžeme pro zpřehlednění kódu definovat něco jako proměnné. V souboru csproj, který pro nás vygenerovalo Visual Studio, můžeme nalézt zakomentované následující cíle:</p>
<pre class="brush: csharp">
  &lt;!-- To modify your build process, add your task inside one of the targets below and uncomment it. --&gt;
  &lt;Target Name="BeforeBuild"&gt;
  &lt;/Target&gt;
  &lt;Target Name="AfterBuild"&gt;
  &lt;/Target&gt;
</pre>
<p>Tyto cíle, jak podle jejich jména jistě tušíte, budou spuštěny před a po buildu. Takže pro spuštění unit testů není potřeba nic většího než je odkomentovat a přidat nějaký obsah. Tím obsahem bude zavolání nunit.exe (nahraďte si svým oblíbeným unit-test frameworkem) a k tomu slouží předdefinovaný úkol (task) Exec, který je standardní součástí instalace MSBuildu.</p>
<pre class="brush: csharp">
&lt;Target Name="AfterBuild"&gt;
  &lt;Exec
    Condition="$(Configuration) == Debug"
    Command="
       &amp;quot;C:\Program Files\NUnit\bin\net-2.0\nunit-console.exe&amp;quot;
       &amp;quot;$(OutputPath)Tests.dll&amp;quot;" /&gt;
&lt;/Target&gt;
</pre>
<p>Atribut Condition určuje podmínku, za které bude úkol spuštěn. Atribut Command určuje příkaz &#8212; sem napíšeme to samé, jako kdybychom chtěli unit testy spustit z příkazové řádky. Uzávorkované a znakem dolaru uvozené části (např. $(OutputPath)), jsou zmíněné &#8222;proměnné&#8220;. Využili jsme dvou proměnných, které pro nás zadefinovalo už Visual Studio. OutputPath určuje cestu, kde budou umístěny sestavy (assembly), které jsou výsledkem buildu. Význam Configuration byl měl být jasný.</p>
<p>Nyní je vše nastaveno. Po každém buildu se spustí unit-testy a pokud některý z nich selže, nunit.exe vrátí kód chyby a celý build selže. Obecně lze následující metodu použít pro spuštění jakékoliv akce ihned po buildu nebo i před buildem.</p>
<p>Update: objevil jsem zajímavý nástroj <a href="http://elegantcode.com/2010/11/30/autotest-net/" title="článek představující AutoTest.Net">AutoTest.Net</a>, který umí zařídit automatické spouštění testů hned po uložení souboru. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stevesindelar.cz/customizace-buildu-ve-vs-automaticke-spusteni-unit-testu/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Entity Framework Code First a enumy</title>
		<link>http://blog.stevesindelar.cz/entity-framework-code-first-a-enumy</link>
		<comments>http://blog.stevesindelar.cz/entity-framework-code-first-a-enumy#comments</comments>
		<pubDate>Sat, 28 Aug 2010 20:52:45 +0000</pubDate>
		<dc:creator>Steves</dc:creator>
				<category><![CDATA[Nezařazené]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[databáze]]></category>

		<guid isPermaLink="false">http://blog.stevesindelar.cz/?p=238</guid>
		<description><![CDATA[Už je to nějaká chvíle, co jsme se na blogu Scotta Guthrie mohli dočíst o &#8222;Code-First&#8220; featuře Entity Frameworku. Pro mě to byl moment, kdy jsem začal o EF uvažovat jako reálné alternativě k NHibernate. EF nicméně stále neumí spoustu věcí, které jsou u NH samozřejmostí. Třeba takové mapování enumů, s čímž jsem se nedávno [...]]]></description>
			<content:encoded><![CDATA[<p>Už je to nějaká chvíle, co jsme se na blogu Scotta Guthrie mohli <a href="http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx">dočíst</a> o &#8222;Code-First&#8220; featuře Entity Frameworku. Pro mě to byl moment, kdy jsem začal o EF uvažovat jako reálné alternativě k NHibernate. EF nicméně stále neumí spoustu věcí, které jsou u NH samozřejmostí. Třeba takové mapování enumů, s čímž jsem se nedávno musel vypořádat. Řešení, která jsem našel na googlu mi úplně nevyhovovala, tak jsem použil vlastní způsob.</p>
<p><span id="more-238"></span></p>
<p>Spočívá v použití mírně upravené varianty tzv. &#8222;<a href="http://www.javacamp.org/designPattern/enum.html">Type safe enum</a>&#8222;. Tento vzor spočívá v tom, že třídě, která má být naším &#8222;enumem&#8220;, skryjeme konstruktor, tak abychom instanci mohli vytvořit jenom &#8222;zevnitř&#8220;, a &#8222;navenek&#8220; nabídneme jenom omezené množství instancí prostřednictvím readonly statických členů.</p>
<pre class="brush: csharp">
    public class Planet
    {
        public static readonly Planet Mercury = new Planet();
        public static readonly Planet Venus = new Planet();
        public static readonly Planet Earth = new Planet();
        public static readonly Planet Mars = new Planet();

        private Planet() {}
    }

    // ....
    Planet p = Planet.Mercury;
    if (p == Planet.Earth) ...
</pre>
<p>Entity Framework ale potřebuje nějak rozlišit jednotlivé instance podle dat. Data zatím nemáme žádná. Můžeme vytvořit jedno-účelnou &#8222;diskriminační&#8220; property například typu int. Navíc privátní parametrický konstruktor by se EF taky nelíbil, takže přidáme další protected bezparametrický konstruktor. To je ústupek, který musíme často podstoupit i v případě NHibernate, privátní konstruktory nemá ráda většina ORM, protože potřebují vytvářet dynamické proxy. Musíme také přetížit operátor porovnání, aby porovnával na základě hodnoty &#8222;diskriminační&#8220; property. Místo jedno-účelové property můžeme případně použít i něco smysluplnějšího, například u dnů v týdnu by to mohlo být jejich pořadové číslo. Výsledná třída bude vypadat následovně:</p>
<pre class="brush: csharp">
    public class Planet
    {
        public static readonly Planet Mercury = new Planet(0);
        public static readonly Planet Venus = new Planet(1);
        public static readonly Planet Earth = new Planet(2);
        public static readonly Planet Mars = new Planet(3);

        private Planet(int dicriminator)
        {
            this.Dicriminator = dicriminator;
        }

        protected Planet() {}

        public int Dicriminator { get; set; }

        public static bool operator ==(Planet planet1, Planet planet2)
        {
            return planet1.Dicriminator == planet2.Dicriminator;
        }

        public static bool operator !=(Planet planet1, Planet planet2)
        {
            return !(planet1 == planet2);
        }

        // spravne bychom meli prekryt i metody Equals a GetHashCode
    }
</pre>
<p>Entity Framework by měl třídu Planet rozpoznat jako &#8222;komplexní typ&#8220; (v řeči NHibernate komponentu) nebo-li třídu, pro kterou nebude vytvářet samostatnou tabulku. Mně ale tohle nefungovalo, takže jsem EF instruoval v tomto směru ručně.</p>
<pre class="brush: csharp">
    public class Context : DbContext
    {
        // ...
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ComplexType&lt;Planet&gt;();
        }
    }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.stevesindelar.cz/entity-framework-code-first-a-enumy/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

