<?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>Michał Jaskólski</title>
	<atom:link href="http://blog.jaskolski.pro/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jaskolski.pro</link>
	<description>I.T. &#124;&#124; E.T. ?</description>
	<lastBuildDate>Wed, 28 Sep 2011 19:39:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Jak ugryźć Mango?</title>
		<link>http://blog.jaskolski.pro/2011/09/28/jak-ugryzc-mango/</link>
		<comments>http://blog.jaskolski.pro/2011/09/28/jak-ugryzc-mango/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 19:20:58 +0000</pubDate>
		<dc:creator>Michał Jaskólski</dc:creator>
				<category><![CDATA[Nieskategoryzowane]]></category>
		<category><![CDATA[mango]]></category>
		<category><![CDATA[windows phone]]></category>
		<category><![CDATA[windows phone 7]]></category>
		<category><![CDATA[wp7]]></category>

		<guid isPermaLink="false">http://blog.jaskolski.pro/?p=555</guid>
		<description><![CDATA[I nastał ten dzień. Dzień długo wyczekiwany przez wszystkich miłośników Windows Phone 7. Całe 7% użytkowników smartfonów przebierało nogami. Pojawiła się oficjalna aktualizacja systemu do wersji 7.1. Postanowiłem zasmakować tego zakazanego owocu. Punktem wyjścia był telefon LG E900 aka Optimus 7 &#8230; <a href="http://blog.jaskolski.pro/2011/09/28/jak-ugryzc-mango/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p><img class="alignleft size-thumbnail wp-image-556" style="border-style: initial; border-color: initial; border-width: initial;" title="Mango" src="http://blog.jaskolski.pro/wp-content/uploads/2011/09/Mango-150x150.jpg" alt="" width="150" height="150" /></p>
<p>I nastał ten dzień. Dzień długo wyczekiwany przez wszystkich miłośników Windows Phone 7. Całe 7% użytkowników smartfonów przebierało nogami. Pojawiła się oficjalna aktualizacja systemu do wersji 7.1.</p>
<p><span id="more-555"></span></p>
<p>Postanowiłem zasmakować tego zakazanego owocu. Punktem wyjścia był telefon LG E900 aka Optimus 7 aka Swift 7 z systemem w wersji Nodo (7.0.3792). Podłączyłem ustrojstwo do komputera, odpalił się Zune i znalazł&#8230; aktualizację do wersji 7.0.7403. &#8222;Pewnie jakieś porządki po wersji beta to będzie robić&#8221; &#8211; mówię sobie. Instaluje. Zainstalowałem. Odświeżenie &#8230;. i jest. Dostępna aktualizacja telefonu do wersji 7.10.7720.68. Jest&#8230; MANGO!!!</p>
<p>Instaluje&#8230; instaluje&#8230; długo&#8230; błąd, James Błąd. A imię jego 8018001E. Google. Google prawdę Ci powie. Cała masa użytkowników LG ma ten sam problem. Chwila czytania i okazuje się, że szczęśliwcy, którym aktualizacja nie wyszła to posiadacze telefonów, które nie pochodzą od operatorów, tylko z &#8222;wolnej&#8221; dystrybucji. Dodatkowo tyczy się to tylko tych z oprogramowaniem (firmware) w wersji 1.0.1.12. Krótkie sprawdzenie &#8211; tak jestem jednym z nich.</p>
<p>Okazuje się, że dawno dawno temu operatorzy wprowadzili do obrotu odpowiednie poprawki, natomiast LG samo w sobie nie wypuściło aktualizacji dla tych bez cyrografów. Bajka &#8211; uwielbiam to. Google. Nie ma nigdzie do ściągnięcia aktualizacji. I co teraz? Lipa.</p>
<p>Po chwili olśnienie &#8211; na XDA Develoeprs <a href="http://forum.xda-developers.com/showthread.php?t=935578" onclick="pageTracker._trackPageview('/outgoing/forum.xda-developers.com/showthread.php?t=935578&amp;referer=');">dostępne jest oryginalne oprogramowanie</a> do LG E900. Może da rade. Procedura nie jest banalna, ale co tam. Ściągnąłem oprogramowanie dla polski oraz wszystkie inne potrzebne narzędzia. W tym miejscu nadmienię, że różnicy między POLAND a EUROPE OPEN nie ma wielkiej &#8211; o wszystkim za chwilę.</p>
<p><strong>Zanim przejdę dalej &#8211; spójrzcie proszę na sam koniec wpisu!</strong></p>
<p>Postępuję zgodnie krokami. Modem się nie chce zainstalować po podłączeniu telefonu. Aaaa trzeba uruchomić telefon w trybie awaryjnym (przycisk aparatu + głośność w dół + zasilanie) i dopiero podłączyć do kompa. Instalują się sterowniki&#8230;. ale nie chcą się skończyć instalować. Odłączam telefon &#8211; zainstalowano &#8211; dziwne? Podłączam ponownie. Wykryty, zainstalowany. Krótka kontrola w menedżerze urządzeń upewnia mnie &#8211; jest modem na porcie COM4.</p>
<p>Odłączam telefon. Odpalam LGDP2_V36_UMTS <strong>z uprawnieniami administratora</strong> (Uruchom jako) &#8211; o tym nie wspomniano. Wczytuję DLLkę, plik z firmware, zaznaczam COM4 (<strong>nie zaznaczam USB mode</strong>). Po potwierdzeniu wyskakuje błąd o braku możliwości odnalezieniu monitora portu. Ignoruje <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Wciskam Start i dopiero teraz podłączam telefon (cały czas będący w trybie awaryjnym). Chwila napięcia&#8230; i tak wgrywa się&#8230; wgrywa. Całość trwa parę minutek, ale kończy się sukcesem <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Mam świeżutki telefon w wersji 7.0.7004 z firmware w wersji 1.1.2.10 &#8211; może teraz zjem Mango.</p>
<p>W tym momencie, aby nie ciągnąć zbyt długo &#8211; oczywiście po dojściu do końca aktualizacji okazuję się, że po języku polskim w interfejsie nie ma śladu. Po zakończeniu aktualizacji do Mango nie ma możliwości dogrania języka. Aby w efekcie go uzyskać należy zrobić co następuje.</p>
<p>Korzystamy z dobrodziejstwa LG, które dało w gratisie aplikacje diagnostyczną, która pozwala grzebać w rejestrze. Aby do niej się dobrać uruchamiam telefon i wybieram ##634# i dzwonię&#8230; dodzwoniłem się, ale pytają i hasło. Znam <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  277634#*#. Wybieram Engineer Menu, Other Setting, Edit registry.</p>
<p>Jako ROOT_PATH wybieram HKEY_LOCAL_MACHINE, jako SUB_PATH wpisuję MUI\Available.</p>
<p>Muszę teraz dodać klucz o nazwie będącej kodem języka w formie szesnastkowej i wartości (łańcuch znaków) odpowiadającej nazwie języka.</p>
<p>Potrzebujemy kod języka polskiego &#8211; z pomocą przychodzi nam <a href="http://msdn.microsoft.com/en-us/library/0h88fahh(v=vs.85).aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/0h88fahh_v=vs.85_.aspx?referer=');">tabela </a>na stronie Microsoftu &#8211; 0415 &#8211; wpisuję to jako KEY, a jako data Polish. Nie wiem, czy nazwa jest istotna, ale na wszelki wypadek tak sobie wpiszę. Można zapewne dopisać inne języki z listy 25 nowych dostępnych w Mano, ale nie sprawdzam.</p>
<p>Klikam Set i Query dla upewnienia się, że zapisałem. Git <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Podłączam do Zune, aktualizacja&#8230;. kończy się wersją 7008. No to teraz NoDo&#8230; ale co to? Zune nie wykrywa aktualizacji. Damn&#8230; Google. Super hiper łopatologiczny sposób.</p>
<p>Wyłączam w telefonie WiFi oraz transmisje danych poprzez sieć komórkową. Podłączam telefon do komputera. W Zune wybieram &#8222;aktualizacja&#8221;&#8230; wyszukiwanie aktualizacji, po ok 3 sekundach &#8222;wyszukiwania&#8221; odłączam komputer od sieci (albo brutalnie kabelkiem albo jak mi się nie chce to wyłączam połączenie sieciowe). Zune znalazł aktualizację do 7392. Jupi. (Nie za pierwszym razem się udało, ale wyczułem moment <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) Włączam sieć, klikam &#8222;Aktualizuj&#8221;. Czekam na koniec&#8230;. jest!</p>
<p>Teraz powinna być 7403&#8230; ale też jej nie ma. Powtarzam manewr &#8211; jest. Aktualizuję. Gotowe &#8211; jest 7403. Szukam Mango &#8211; błąd połączenia. Jeszcze raz. Jest &#8211; aktualizacja dostępna! Aktualizuję&#8230;.. zrobione. Tak, jest, mam mango 7.10&#8230;. Wchodzę w ustawienia, język wyświetlania &#8211; tak jest Polski <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Wybieram, ciesze się jak dziecko.</p>
<p>I tym oto prostym sposobem mogę cieszyć się LG E900 z Mango i pełną polonizacją. Tylko dlaczego do <strong>cholery</strong> nadal nie mogę po prostu wysłać sobie zdjęcia przez Bluetooth&#8230; dlaczego nie mam dostępu do wszystkich aplikacji w markecie (no ale już mam dostęp z polskiego konta live do marketu i xbox &#8211; postęp)&#8230;  ale to być może historia na inny wpis <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Aha &#8211; nie muszę chyba wspominać, że cała procedura sprowadza się do tego, że w telefonie nie pozostanie ślad po ustawieniach, plikach&#8230;</strong></p>
<div class="shr-publisher-555"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.jaskolski.pro/2011/09/28/jak-ugryzc-mango/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Niskobudżetowe repozytorium NuGet</title>
		<link>http://blog.jaskolski.pro/2011/07/25/niskobudzetowe-repozytorium-nuget/</link>
		<comments>http://blog.jaskolski.pro/2011/07/25/niskobudzetowe-repozytorium-nuget/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 18:47:02 +0000</pubDate>
		<dc:creator>Michał Jaskólski</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Technologia]]></category>
		<category><![CDATA[biblioteki]]></category>
		<category><![CDATA[nuget]]></category>

		<guid isPermaLink="false">http://blog.jaskolski.pro/?p=537</guid>
		<description><![CDATA[Dziś krótki artykuł z cyklu &#8222;małe a cieszy&#8221; Chyba każdy programista w trakcie swojego życia zbiera jakieś przydatne kawałki kodu. Niektórzy tworzą z nich drobne biblioteki, inni całe frameworki. To czy jest to praktyka zła, czy dobra nie jest tematem &#8230; <a href="http://blog.jaskolski.pro/2011/07/25/niskobudzetowe-repozytorium-nuget/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p><a href="http://blog.jaskolski.pro/wp-content/uploads/2011/07/nuget-64x64.png"><img class="alignleft size-full wp-image-553" title="nuget-64x64" src="http://blog.jaskolski.pro/wp-content/uploads/2011/07/nuget-64x64.png" alt="" width="64" height="64" /></a>Dziś krótki artykuł z cyklu &#8222;małe a cieszy&#8221; <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Chyba każdy programista w trakcie swojego życia zbiera jakieś przydatne kawałki kodu. Niektórzy tworzą z nich drobne biblioteki, inni całe frameworki. To czy jest to praktyka zła, czy dobra nie jest tematem tej rozprawki. Wszystkim nam gdzieś tam jednak przyświeca idea DRY (Do not Repeat Yourself). Jak ją sobie zrealizujemy, to już zależy od nas. Przynajmniej w naszych prywatnych projektach. Z owymi „przydasiami” wiąże się pewien problem. Gdy już stworzymy sobie szereg bibliotek, chcielibyśmy je wykorzystać w różnych projektach.</p>
<p>Osobiście przeszedłem przez etap repozytorium binarek trzymanych w SVN, sciąganych do wyznaczonego katalogu; ręcznego dodawania do nich referencji; czy tworzenia instalatorów WiX, które pakowały binarki do GAC oraz do katalogu z „referencyjnymi bibliotekami”. Miało to tyle wad co zalet, a rozwiązanie z WiXem było dodatkowo pracochłonne.</p>
<p>Na szczęście na horyzoncie pojawił się NuGet.</p>
<p>O tym, czym NuGet jest, chyba nikomu ze światka około .NETowego mówić nie muszę. Gdyby jednak ktoś nie kojarzył, odsyłam na <a href="http://nuget.codeplex.com" onclick="pageTracker._trackPageview('/outgoing/nuget.codeplex.com?referer=');">oficjalną stronę projektu</a>, gdzie możecie w szczegółach zaznajomić się z projektem.</p>
<p>W wielkim skrócie to narzędzie, które korzystając ze zdefiniowanych repozytoriów, potrafi dodać do projektu niezbędne referencje, uprzednio ściągając wszystkie potrzebne pliki. Potrafi także wprowadzić zmiany w konfiguracji i wiele, wiele innych fajnych rzeczy. A to wszystko możemy zrobić z poziomu menu kontekstowego w Visual Studio. Bajka!</p>
<p>Myśl, która automatycznie przychodzi do głowy to: „ja chcę takie repozytorium; będę mógł publikować paczuszki, z których będę później korzysał w różnych projektach, a nawet będe mógł się nimi podzielić ze współpracownikami.”.</p>
<p>Istnieje publiczne repozytorium NuGet, ale z pewnością nie chcemy tam umieszczać prywatnych rzeczy (przynajmniej do czasu kiedy zdecydujemy się opublikować wyniki naszej ciężkiej pracy).</p>
<p>Dostępne rozwiązania hostujące repozytoria działają tylko na platformie Windows, a hosting Windowsowy do najtańszych nie należy. Własnego rozwiązania w np. PHP pisać nam sie nie chce. Jak więc sobie z tym poradzić? Dzięki temu, że ktoś wykonał kawałek dobrej roboty i pomyślał, repozytorium NuGet możemy mieć w postaci katalogu z paczkami .nupkg.</p>
<p>Takie repozytorium możemy synchronizować za pomocą <a href="http://git-scm.com/ " onclick="pageTracker._trackPageview('/outgoing/git-scm.com/?referer=');">Git</a> dla przykładu.</p>
<p>Zanim przystąpimy do pracy musimy zaopatrzyć się w potrzebne narzędzia. Poza instalacja rozszerzenia NuGet do Visual Studio 2010, które począwszy od dodatku Service Pack 1 zainstalowane jest domyślnie, musimy zaopatrzyć się w <a href="http://nuget.codeplex.com/releases" onclick="pageTracker._trackPageview('/outgoing/nuget.codeplex.com/releases?referer=');">narzędzie linii poleceń dostepne na stronie projektu</a>, które przyda się do tworzenia paczek.</p>
<p>Zatem do dzieła – stwórzmy i skonfigurujmy repozytorium. Zakładam, że nasze repozytiurm będzie współdzielone pomiędzy kilka osób, zatem gdzieś na dedykowanym serwerze tworzymy puste, współdzielone repozytorium (ja posiłkuję się po stronie serwerowej technologią okołopingwinową, więc takiej będę się tu trzymał). Dla ustalenia uwagi przyjmijmy, że lokalnie repozytorium będzie znajdować się w katalogu D:\Packages. Na serwerze, gdzie hostujemy repozytoria, tworzymy nowe, a następnie klonujemy do wspomnianego katalogu. Katalog ten następnie dodajemy w Visual Studio:</p>
<p style="text-align: left;"><a href="http://blog.jaskolski.pro/wp-content/uploads/2011/07/PackageManagerSettings01.png"><img class="aligncenter size-medium wp-image-538" title="PackageManagerSettings01" src="http://blog.jaskolski.pro/wp-content/uploads/2011/07/PackageManagerSettings01-300x147.png" alt="" width="300" height="147" /></a>Dodajemy nowe repozytorium wprowadzając nazwę oraz lokalizację na dysku lokalnym:</p>
<p style="text-align: left;"><a href="http://blog.jaskolski.pro/wp-content/uploads/2011/07/PackageManagerSettings02.png"><img class="aligncenter size-medium wp-image-539" title="PackageManagerSettings02" src="http://blog.jaskolski.pro/wp-content/uploads/2011/07/PackageManagerSettings02-300x194.png" alt="" width="300" height="194" /></a></p>
<p style="text-align: left;">Repozytorium skonfigurowane. Pozostaje tylko je czymś wypełnić.</p>
<p style="text-align: left;">Zanim przystąpimy do tworzenia biblioteki musimy wykonać dwa kroki wstępne:</p>
<ul>
<li>Do zmiennej systemowej PATH dodać scieżkę do sciągniętego uprzednio pliku NuGet.exe</li>
<li>Zdefiniować zmienna systemowa PACKAGESDIR (dla przykładu), która będzie wskazywać katalog docelowy na tworzone paczki.</li>
</ul>
<div><span class="Apple-style-span" style="line-height: 18px;">Zmienną PACKAGESDIR wprowadzamy, aby uniknąć kodowania na sztywno w opcjach projektu lokalizacji docelowej. Dzięki temu prostemu zabiegowi uzyskujemy elastyczność, a każdy członek zespołu może mieć repozytorium gdzie chce.</span></div>
<div><span class="Apple-style-span" style="line-height: 18px;">W Visual Studio tworzymy nowy projekt &#8211; dla przykładu bibliotekę. W opcjach projektu dodajemy następujący kod jako Post Build Event:</span></div>
<pre class="brush: plain; title: ; notranslate">

cd $(ProjectDir)

NuGet.exe pack $(ProjectFileName) -OutputDirectory $(PACKAGESDIR) -Properties Configuration=Release
</pre>
<p><a href="http://blog.jaskolski.pro/wp-content/uploads/2011/07/PostBuildOptions.png"><img class="aligncenter size-medium wp-image-540" title="PostBuildOptions" src="http://blog.jaskolski.pro/wp-content/uploads/2011/07/PostBuildOptions-300x210.png" alt="" width="300" height="210" /></a>W pliku AssemblyInfo.cs dodajemy co najmniej takie atrybuty:</p>
<pre class="brush: csharp; title: ; notranslate">
[assembly: AssemblyTitle(&quot;SampleLibrary&quot;)]
[assembly: AssemblyDescription(&quot;SampleLibrary&quot;)]
[assembly: AssemblyCompany(&quot;ACME&quot;)]
[assembly: AssemblyProduct(&quot;SampleLibrary&quot;)]
[assembly: AssemblyCopyright(&quot;Copyright © ACME 2011&quot;)]
[assembly: AssemblyVersion(&quot;1.0.0.0&quot;)]
[assembly: AssemblyFileVersion(&quot;1.0.0.0&quot;)]
</pre>
<p>Po zapisaniu zmian i przekompilowaniu projektu, w katalogu D:\Packages pojawi się nowa paczka. W powyższym przykładzie opis paczki oraz podstawowe informacje o niej pobierane są z pliku projektu. Jeżeli zależy nam na większej kontroli, możemy utworzyć dla projektu plik .nuspec z dokładną specyfikacją paczki. Szczegóły formatu znajdziecie w dokumentacji projektu NuGet.</p>
<p>Po poprawnej kompilacji możemy zweryfikować, czy paczka jest dostępna. Z menu kontekstowego gałęzi References wybieramy opcję umożliwiającą dodanie referencji do paczki:</p>
<p><a href="http://blog.jaskolski.pro/wp-content/uploads/2011/07/AddLibraryPackageReference01.png"><img class="aligncenter size-medium wp-image-541" title="AddLibraryPackageReference01" src="http://blog.jaskolski.pro/wp-content/uploads/2011/07/AddLibraryPackageReference01-300x181.png" alt="" width="300" height="181" /></a>Jak widać na załączonym obrazku, nowo utworzona paczka jest gotowa do instalacji:</p>
<p><a href="http://blog.jaskolski.pro/wp-content/uploads/2011/07/AddLibraryPackageReference02.png"><img class="aligncenter size-medium wp-image-542" title="AddLibraryPackageReference02" src="http://blog.jaskolski.pro/wp-content/uploads/2011/07/AddLibraryPackageReference02-300x171.png" alt="" width="300" height="171" /></a></p>
<p>Pamiętajmy, aby po utworzeniu paczek zsynchronizować repozytorium Git. Inni niech też coś z tego mają <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Jeżeli paczki w repozytorium odświeżają się częściej niż ich numery wersji, istnieje konieczność ich ponownego pobrania. Z pudełka nie dostajemy obecnie nic, co by mogło nam w tym pomóc. Po chwili googlania możemy jednak znaleźć <a href="http://weblogs.asp.net/soever/archive/2011/05/04/nuget-refreshing-nuget-packages-in-packages-folder-during-development.aspx" onclick="pageTracker._trackPageview('/outgoing/weblogs.asp.net/soever/archive/2011/05/04/nuget-refreshing-nuget-packages-in-packages-folder-during-development.aspx?referer=');">potrzebne narzędzie</a>.</p>
<p>Przedstawione rozwiązanie to najprostszy przypadek jaki można sobie wyobrazić. NuGet posiada wiele opcji, z których można skorzystać, aby utworzyć paczki dostosowane do własnych potrzeb. Zachęcam do zagłębienia się w szczegóły. Naprawdę warto!</p>
<div class="shr-publisher-537"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.jaskolski.pro/2011/07/25/niskobudzetowe-repozytorium-nuget/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Proste pogaduchy między procesami, czyli coś lekkiego o .NET Remoting i WCF</title>
		<link>http://blog.jaskolski.pro/2011/01/21/proste-pogaduchy-miedzy-procesami-czyli-cos-lekkiego-o-net-remoting-i-wcf/</link>
		<comments>http://blog.jaskolski.pro/2011/01/21/proste-pogaduchy-miedzy-procesami-czyli-cos-lekkiego-o-net-remoting-i-wcf/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 11:59:43 +0000</pubDate>
		<dc:creator>Michał Jaskólski</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ipc]]></category>
		<category><![CDATA[remoting]]></category>
		<category><![CDATA[wcf]]></category>

		<guid isPermaLink="false">http://blog.jaskolski.pro/?p=523</guid>
		<description><![CDATA[Przyznam szczerze, że dotychczas z komunikacją między różnymi aplikacjami lub ich warstwami spotykałem się głownie w aspekcie usługowo-webowym. Taki scenariusz sprowadza się do takiego a nie innego wykorzystania webservice lub pochodnego ustrojstwa. Co jednak można zastosować jeżeli chcemy aby dwie &#8230; <a href="http://blog.jaskolski.pro/2011/01/21/proste-pogaduchy-miedzy-procesami-czyli-cos-lekkiego-o-net-remoting-i-wcf/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p><a href="http://blog.jaskolski.pro/wp-content/uploads/2011/01/oHuov.png"><img class="alignleft size-thumbnail wp-image-524" title="WCF Logo" src="http://blog.jaskolski.pro/wp-content/uploads/2011/01/oHuov-150x67.png" alt="" width="150" height="67" /></a>Przyznam szczerze, że dotychczas z komunikacją między różnymi aplikacjami lub ich warstwami spotykałem się głownie w aspekcie usługowo-webowym. Taki scenariusz sprowadza się do takiego a nie innego wykorzystania webservice lub pochodnego ustrojstwa. Co jednak można zastosować jeżeli chcemy aby dwie nasze aplikacje miały możliwość pogadania ze sobą na lokalnej maszynie?</p>
<p><span id="more-523"></span></p>
<p>Rozwiązań jest sporo albo i jeszcze więcej. Poczynając od SendMessage z Win32 API, współdzielonej pamięci, webservice, TCP,  COM, DCOM na named pipes kończąc. Jednak chcemy czegoś prostego w implementacji, w końcu programiści są leniwi (w pozytywnym tego słowa znaczeniu <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ). Postaram się przedstawić dwa scenariusze, z których jeden należy od razu wyeliminować jako obsolete &#8211; jednak jako ciekawostkę przytoczę. A drugim będzie WCF &#8211; i tą cześć można potraktować jako swoisty quickstart do tej technologii. Mimo że to już nic nowego miałem wenę, aby o tym napisać <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Dla ustalenia uwagi przyjmiemy scenariusz, w którym aplikacja A (Host) będzie świadczyć usługi na rzecz aplikacji B (Client), które to sprowadzą się do prostej operacji na łańcuchu znaków i równie prostej operacji pobrania jakiejś paczuszki, która będzie typem nieco bardziej skomplikowanym.</p>
<p>Dawno, dawno temu jak jeszcze .NET miał 1 w numerze wersji istniała technologia .NET Remoting. Ustrojstwo które przypomina w użyciu nieco technologię COM, a obecnie jest niezalecane przez Microsoft na rzecz WCF.</p>
<p>Rzeczą numer jeden jest umowa stanowiąca co oferuje host. Umowę taką definiujemy w postaci kontraktu &#8211; interfejsu. Na potrzeby .NET Remoting wystarczy zdefiniować interfejs taki jak na załączonym obrazku:</p>
<pre class="brush: csharp; title: ; notranslate">
namespace Contracts
{
    public interface ISampleService
    {
        string ProcessMessage(string message);
        Payload GetPayload();
    }
    [Serializable]
    public class Payload
    {
        public DateTime TimeStamp { get; set; }
        public int Value { get; set; }
        public Payload()
        {
            TimeStamp = DateTime.Now;
            Value = (new Random()).Next();
        }
        public override string ToString()
        {
            return String.Format(&quot;{0};{1}&quot;, TimeStamp, Value);
        }
    }
}
</pre>
<p>Ponieważ Payload jak widać jest paczuszką, która będzie przesyłana między procesami, musi istnieć możliwość jej serializacji &#8211; oto tajemnica atrybutu [Serializable].</p>
<p>Niezwykle skomplikowany kod Hosta wygląda następująco:</p>
<pre class="brush: csharp; title: ; notranslate">
namespace RemotingHost
{
    class Program
    {
        static void Main(string[] args)
        {
            var channel = new IpcChannel(&quot;RemotingHostChannel&quot;);
            var serviceType = typeof(SampleService);
            ChannelServices.RegisterChannel(channel, false);
            RemotingConfiguration.RegisterWellKnownServiceType(serviceType,
                &quot;SampleService&quot;,
                WellKnownObjectMode.Singleton);
            Console.WriteLine(&quot;Host is running, hit &lt;RETURN&gt; to stop...&quot;);
            Console.ReadLine();
        }
    }
    public class SampleService : MarshalByRefObject, ISampleService
    {
        #region ISampleService Members
        public string ProcessMessage(string message)
        {
            int processID = Process.GetCurrentProcess().Id;
            Console.WriteLine(&quot;{1}: Recieved message: {0}&quot;, message, processID);
            return String.Format(&quot;{1}: your input is \&quot;{0}\&quot;&quot;,
                                 message, processID);
        }
        public Payload GetPayload()
        {
            int processID = Process.GetCurrentProcess().Id;
            var result = new Payload();
            Console.WriteLine(&quot;{0}: generated payload {1}&quot;, processID, result);
            return result;
        }
        #endregion
    }
}
</pre>
<p>Kilka linijek na krzyż i mamy już kawałek aplikacji, która umie świadczyć wybrane usługi klientom. Jako parametr konstruktora klasy IpcChannel podaliśmy nazwę kanału, natomiast do metody RegisterWellKnownServiceType przekazujemy oczywiście typ usługi, jej nazwę oraz określamy czy każde żądanie będzie obsługiwane przez nową instancję klasy implementującej usługę, czy można zadowolić się jedną.<br />
Dziedziczenie SampleService z MarshalByRefObject jest niezwykle istotne, gdyż klient musi mieć możliwośc otrzymania referencji do obiektu usługi, kiedy będzie z niej korzystał.</p>
<p>Reszta nie wymaga komentarza, a w potrzebie zawsze znajdzie się przyjaciel w postaci F1 <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Klient jest równie prosty w implementacji:</p>
<pre class="brush: csharp; title: ; notranslate">
namespace RemotingClient
{
    class Program
    {
        static void Main(string[] args)
        {
            string message;
            var service = (ISampleService) Activator.GetObject(typeof (ISampleService),
                String.Format(&quot;ipc://{0}/{1}&quot;, &quot;RemotingHostChannel&quot;,
                    &quot;SampleService&quot;));
            Console.WriteLine(&quot;Write something and you'll get a surprise <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  (empty to exit)&quot;);
            while (!String.IsNullOrEmpty(message = Console.ReadLine()))
            {
                Console.WriteLine(&quot;{0}&quot;, service.ProcessMessage(message));
                Console.WriteLine(&quot;Your surprise: {0}&quot;, service.GetPayload());
            }
        }
    }
}
</pre>
<p>Chyba jedyną ciekawostką jest tutaj &#8222;adres&#8221; usługi, w którym rozpoznajemy znajome łańcuchy użyte w kodzie hosta. Wszystko śmiga, różne procesy komunikują się ze sobą i są szcześliwe, jak widać na załączonym obrazku:</p>
<p><a href="http://blog.jaskolski.pro/wp-content/uploads/2011/01/NETRemotingSample.png"><img class="aligncenter size-medium wp-image-530" title="NETRemotingSample" src="http://blog.jaskolski.pro/wp-content/uploads/2011/01/NETRemotingSample-300x172.png" alt="" width="300" height="172" /></a></p>
<p>Ponieważ, tak jak wspomniałem, .NET Remoting jest obsolete, zrealizujemy tą samą funkcjonalność z wykorzystaniem modnego i lubianego Windows Communication Foundation <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>WCF jest prosty jak ABC gdzie:</p>
<ul>
<li>A = Address, czyli adres pod którą dostępna jest usługa</li>
<li>B = Binding, czyli sposób w jaki można się z tą usługą porozumieć (protokół, transport jak zwał tak zwał)</li>
<li>C = Contract, czyli wspomniana wcześniej umowa o świadczenie usług <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p>Kontrakt definiujemy niemal identycznie jak uprzdnio, dodając kilka WCFowych ozdobników:</p>
<pre class="brush: csharp; title: ; notranslate">
namespace Contracts
{
    [ServiceContract]
    public interface ISampleService
    {
        [OperationContract]
        string ProcessMessage(string message);
        [OperationContract]
        Payload GetPayload();
    }
    [DataContract]
    public class Payload
    {
        [DataMember]
        public DateTime TimeStamp { get; set; }
        [DataMember]
        public int Value { get; set; }
        public Payload()
        {
            TimeStamp = DateTime.Now;
            Value = (new Random()).Next();
        }
        public override string ToString()
        {
            return String.Format(&quot;{0};{1}&quot;, TimeStamp, Value);
        }
    }
}
</pre>
<p>Odpowiednie atrybuty instruują WCF co jest czym i co jest dostępne dla klienta. Metody interfejsu które nie są opatrzone [OperationContract] oraz członkowie klasy bez [DataMember] nie będą widoczne po drugiej stronie barykady.<br />
Istotna rzecz: jakby ktoś z jakiegoś niewyjaśnionego powodu chciał łączyć WCF z .NET Remoting &#8211; dobra nowina, .NET Remoting może korzystać z tej samej definicji kontraktu co WCF. Ozdobniki nie stanowią przeszkody.</p>
<p>Ponieważ chcemy komunikować się między procesami na tej samej maszynie, użyjemy efektywnego transportu named pipes.<br />
I tak oto prezentuje się kod hosta:</p>
<pre class="brush: csharp; title: ; notranslate">
namespace WCFHost
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var host = new ServiceHost(typeof(SampleService),
                    new Uri(&quot;net.pipe://localhost&quot;)))
            {
                host.AddServiceEndpoint(typeof(ISampleService), new NetNamedPipeBinding(), &quot;SampleService&quot;);
                host.Open();
                Console.WriteLine(&quot;Host is running, hit &lt;RETURN&gt; to stop...&quot;);
                Console.ReadLine();
                host.Close();
            }
        }
    }
    public class SampleService : ISampleService
    {
        #region ISampleService Members
        public string ProcessMessage(string message)
        {
            int processID = Process.GetCurrentProcess().Id;
            Console.WriteLine(&quot;{1}: Recieved message: {0}&quot;, message, processID);
            return String.Format(&quot;{1}: your input is \&quot;{0}\&quot;&quot;,
                                 message, processID);
        }
        public Payload GetPayload()
        {
            int processID = Process.GetCurrentProcess().Id;
            var result = new Payload();
            Console.WriteLine(&quot;{0}: generated payload {1}&quot;, processID, result);
            return result;
        }
        #endregion
    }
}
</pre>
<p>Kod sam się objaśnia, zgodnie z WCFowym ABC konigurowana jest usługa. Warto zwrócić uwagę, na to iż klasa SampleService nie dziedziczy juz po MarshalByRefObj.</p>
<p>Klient równie prosty:</p>
<pre class="brush: csharp; title: ; notranslate">

namespace WCFClient
{
    class Program
    {
        static void Main(string[] args)
        {
            var factory = new ChannelFactory&lt;ISampleService&gt;(new NetNamedPipeBinding(),
                new EndpointAddress(&quot;net.pipe://localhost/SampleService&quot;)
                );
            var factory = new ChannelFactory&lt;ISampleService&gt;(&quot;SampleService&quot;);
            var service = factory.CreateChannel();
            string message;
            Console.WriteLine(&quot;Write something and you'll get a surprise <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  (empty to exit)&quot;);
            while (!String.IsNullOrEmpty(message = Console.ReadLine()))
            {
                Console.WriteLine(&quot;{0}&quot;, service.ProcessMessage(message));
                Console.WriteLine(&quot;Your surprise: {0}&quot;, service.GetPayload());
            }
        }
    }
}
</pre>
<p>I jak widać na kolejnym obrazku: znów działa <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://blog.jaskolski.pro/wp-content/uploads/2011/01/WCFSample.png"><img class="aligncenter size-medium wp-image-529" title="WCFSample" src="http://blog.jaskolski.pro/wp-content/uploads/2011/01/WCFSample-300x183.png" alt="" width="300" height="183" /></a></p>
<p>Proste jak ABC, czyż nie?<br />
STOP!<br />
Może być jeszcze prostsze a przy okazji bardziej elastyczne. WCF został tak zaprojektowany, aby każdą usługę i klienta można było dynamicznie konfigurować bez potrzeby rekompilacji kodu.<br />
Zmieńmy zatem aplikację hosta dodając do niej plik konfiguracyjny:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;configuration&gt;
  &lt;system.serviceModel&gt;
    &lt;services&gt;
      &lt;service  name=&quot;WCFHost.SampleService&quot;&gt;
        &lt;endpoint address=&quot;net.pipe://localhost/SampleService&quot;
                  binding=&quot;netNamedPipeBinding&quot;
                   contract =&quot;Contracts.ISampleService&quot;/&gt;
      &lt;/service&gt;
    &lt;/services&gt;
  &lt;/system.serviceModel&gt;
&lt;/configuration&gt;
</pre>
<p>Teraz host jest jeszcze prostszy i czytelniejszy:</p>
<pre class="brush: csharp; title: ; notranslate">
namespace WCFHost
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var host = new ServiceHost(typeof(SampleService)))
            {
                host.Open();
                Console.WriteLine(&quot;Host is running, hit &lt;RETURN&gt; to stop...&quot;);
                Console.ReadLine();
                host.Close();
            }
        }
    }
}
</pre>
<p>Klasa ServiceHost automatycznie na podstawie nazwy typu usługi (typeof) wspomnianej w atrubycie name elementu <service> odszuka konfigurację i ustawi binding, kontrakt oraz adres.</p>
<p>Z klientem sytuacja jest analogiczna, konfiguracja:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;configuration&gt;
  &lt;system.serviceModel&gt;
    &lt;client&gt;
      &lt;endpoint address=&quot;net.pipe://localhost/SampleService&quot;
                contract=&quot;Contracts.ISampleService&quot;
                binding=&quot;netNamedPipeBinding&quot;
                name=&quot;SampleService&quot;/&gt;
    &lt;/client&gt;
  &lt;/system.serviceModel&gt;
&lt;/configuration&gt;
</pre>
<p>I oczyszczony kod:</p>
<pre class="brush: csharp; title: ; notranslate">
namespace WCFClient
{
    class Program
    {
        static void Main(string[] args)
        {
            var factory = new ChannelFactory&lt;ISampleService&gt;(&quot;SampleService&quot;);
            var service = factory.CreateChannel();
            string message;
            Console.WriteLine(&quot;Write something and you'll get a surprise <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  (empty to exit)&quot;);
            while (!String.IsNullOrEmpty(message = Console.ReadLine()))
            {
                Console.WriteLine(&quot;{0}&quot;, service.ProcessMessage(message));
                Console.WriteLine(&quot;Your surprise: {0}&quot;, service.GetPayload());
            }
        }
    }
}
</pre>
<p>Prawda że ładniej?</p>
<p>Oczywiście to co opisałem jest wirzchołkiem góry lodowej jeżeli chodzi o WCF, ale mam głęboką nadzieję że może jakiejś zbłąkanej duszy pozwoli rozpocząć przygodę z WCF w bezbolesny sposób, bez konieczności przekopania się przez miliony stron opisów na początek.</p>
<p>Ponieważ zakochałem się z wzajemnością w <a href="http://git-scm.com/" onclick="pageTracker._trackPageview('/outgoing/git-scm.com/?referer=');">Git</a>, kod źródłowy przykładów możecie znależć na <a href="https://github.com/emdzej/blog_samples_ipc" onclick="pageTracker._trackPageview('/outgoing/github.com/emdzej/blog_samples_ipc?referer=');">git://github.com/emdzej/blog_samples_ipc.git</a></p>
<div class="shr-publisher-523"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.jaskolski.pro/2011/01/21/proste-pogaduchy-miedzy-procesami-czyli-cos-lekkiego-o-net-remoting-i-wcf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Templated Controls a pomroczność jasna</title>
		<link>http://blog.jaskolski.pro/2011/01/20/templated-controls-a-pomrocznosc-jasna/</link>
		<comments>http://blog.jaskolski.pro/2011/01/20/templated-controls-a-pomrocznosc-jasna/#comments</comments>
		<pubDate>Thu, 20 Jan 2011 13:47:11 +0000</pubDate>
		<dc:creator>Michał Jaskólski</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[controls]]></category>
		<category><![CDATA[template]]></category>
		<category><![CDATA[web controls]]></category>

		<guid isPermaLink="false">http://blog.jaskolski.pro/?p=513</guid>
		<description><![CDATA[Dzisiejszego pięknego i powtórnie zimowego dnia zaszła potrzeba stworzenia kontrolki, która miałaby dwa wzorce zawartości: nagłowek i ciało. Wszystko szło pięknie. Stworzyłem sobie kontenery do wzorców, odpowiednią kontrolke i wszystkie inne potrzebne rzeczy. Gdy jednak przyszło do wykorzystania okazało się, &#8230; <a href="http://blog.jaskolski.pro/2011/01/20/templated-controls-a-pomrocznosc-jasna/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p><a href="http://blog.jaskolski.pro/wp-content/uploads/2011/01/ASP-NET-Logo_thumb.gif"><img class="alignleft size-thumbnail wp-image-514" title="ASP.NET" src="http://blog.jaskolski.pro/wp-content/uploads/2011/01/ASP-NET-Logo_thumb-150x87.gif" alt="" width="150" height="87" /></a></p>
<p>Dzisiejszego pięknego i powtórnie zimowego dnia zaszła potrzeba stworzenia kontrolki, która miałaby dwa wzorce zawartości: nagłowek i ciało. Wszystko szło pięknie. Stworzyłem sobie kontenery do wzorców, odpowiednią kontrolke i wszystkie inne potrzebne rzeczy. Gdy jednak przyszło do wykorzystania okazało się, że kontrolki umieszczone wewnątrz wzorców nie mają odwołać w pliku designera, ani nie są dostępne &#8222;globalnie&#8221; na stronie. Jakby nie patrzeć całkiem normalne zachwoanie tego typu zwierza, do jakiego mogliśmy przyzyczaić się korzystając z DataGrid, Repeater i innych tego typu ustrojstw.</p>
<p><span id="more-513"></span></p>
<p>Wiedziałem, że jest możliwość, aby kontrolki wewnętrzne były widoczne &#8222;od ręki&#8221; i aby nie istniała konieczność używania FindControl w kontenerach&#8230; tylko jak? Totalne zaćmienie umysłu, nawet Google nie pomogło. Na szczęście przewinęło się słowo klucz <strong>TemplateInstanceAttribute</strong>. Jak już słowo klucz się znalazło, przypomniałem sobie o oczywistej oczywistości, czyli kontrolce UpdatePanel, która ma ContentTemplate, który zachowuje się dokładnie tak jak to sobie wymarzyłem.</p>
<p>Niniejsza wzmianka jest więc dla &#8222;potomności&#8221; &#8211; w przypadku jakby ktoś, kiedyś z niewyjaśnionych względów szukał rozwiązania a miał chwilowe zaćmienie <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Do rzeczy. Zrobimy sobie kontrokę, która będzie pojedyńczym wystąpieniem elementu akordeonu &#8211; czyli czymś co ma nagłowek i zwijane ciałko. Całość będzie DIVem, nagłowek i ciało będzie także DIVami &#8211; stąd wykorzystanie Panel jako klasy bazowej zarówno dla kontrolki jak i kontenerów.</p>
<p>Kontenerki wyglądają tak:</p>
<pre class="brush: csharp; title: ; notranslate">
namespace TemplatedControlSample
{
    public class HeaderTemplateContainer : Panel, INamingContainer
    {
        public string Title { get; set; }
    }
 public class BodyTemplateContainer : Panel, INamingContainer
    {
    }
}
</pre>
<p>A kontroleczka tak:</p>
<pre class="brush: csharp; title: ; notranslate">

namespace TemplatedControlSample
{
    [ParseChildren(true)]
    [PersistChildren(true)]
    public class SimpleTemplatedControl : Panel
    {
        protected ITemplate _HeaderTemplate;
        protected ITemplate _BodyTempalte;
        public virtual string Title
        {
            get { return (string) ViewState[&quot;Title&quot;]; }
            set { ViewState[&quot;Title&quot;] = value; }
        }
        [TemplateInstance(TemplateInstance.Single)]
        [TemplateContainer(typeof(HeaderTemplateContainer))]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public virtual ITemplate HeaderTemplate
        {
            get { return _HeaderTemplate; }
            set { _HeaderTemplate = value; }
        }
        [TemplateInstance(TemplateInstance.Single)]
        [TemplateContainer(typeof(BodyTemplateContainer))]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public virtual ITemplate BodyTemplate
        {
            get { return _BodyTempalte; }
            set { _BodyTempalte = value; }
        }
        protected override void CreateChildControls()
        {
            ITemplate headerTempalte = _HeaderTemplate ?? new DefaultHeaderTemplate();
            ITemplate bodyTemplate = _BodyTempalte;
            HeaderTemplateContainer headerContainer = new HeaderTemplateContainer()
            {
                Title = Title,
                ID = &quot;Header&quot;,
                BackColor = Color.Blue
            };
            headerTempalte.InstantiateIn(headerContainer);
            Controls.Add(headerContainer);
            headerContainer.DataBind();
            BodyTemplateContainer bodyContainer = new BodyTemplateContainer()
            {
                ID = &quot;Body&quot;,
                BackColor = Color.Gray
            };
            if (bodyTemplate != null)
            {
                bodyTemplate.InstantiateIn(bodyContainer);
            }
            Controls.Add(bodyContainer);
            bodyContainer.DataBind();
            headerContainer.Attributes[&quot;onclick&quot;] =
                String.Format(&quot;jQuery('#{0}').toggle();&quot;, bodyContainer.ClientID);
        }
    }
}
</pre>
<p>Cała magia tkwi w dodaniu atrybutu [TemplateInstance(TemplateInstance.Single)] do właściwości wzorców. Ot cała filozofia&#8230; eh</p>
<p>Pragnę zwrócić uwagę na dodanie atrybutu  [ParseChildren(true)] do klasy kontrolki. Panel ma ten atrybut ustawiony w drugą stronę, jednak gdybyśmy tego nie nadpisali, wzorce nie byłyby przeparsowane przez ASP.NET i wszystko wylądowałoby jako zawartość Panel.</p>
<p>Jak możecie przekonać się sami ściągając kod z <a href="https://github.com/emdzej/blog_samples_templatedcontrol" onclick="pageTracker._trackPageview('/outgoing/github.com/emdzej/blog_samples_templatedcontrol?referer=');">git://github.com/emdzej/blog_samples_templatedcontrol.git</a> wszystko śmiga jak chciałem <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Podziękowania dla Łukasza, który był źródłem &#8222;przewinięcia się&#8221; słowa klucza <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="shr-publisher-513"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.jaskolski.pro/2011/01/20/templated-controls-a-pomrocznosc-jasna/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google eBooks wystartowało</title>
		<link>http://blog.jaskolski.pro/2010/12/07/google-ebooks-wystartowalo/</link>
		<comments>http://blog.jaskolski.pro/2010/12/07/google-ebooks-wystartowalo/#comments</comments>
		<pubDate>Tue, 07 Dec 2010 08:58:18 +0000</pubDate>
		<dc:creator>Michał Jaskólski</dc:creator>
				<category><![CDATA[Wydarzenia]]></category>
		<category><![CDATA[ebook]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://blog.jaskolski.pro/?p=509</guid>
		<description><![CDATA[No to się doczekaliśmy&#8230; Google odpaliło własną książkową machinę. Na dobry początek dostępne jest &#8211; bagatela &#8211; 3 mln tytułów. Dostępne niestety w US. Poza krainą Wuja Sama dostępne są publikacje z domeny publicznej. Jak pisze Google, negocjują z wydawcami. &#8230; <a href="http://blog.jaskolski.pro/2010/12/07/google-ebooks-wystartowalo/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><div>
<p><a href="http://blog.jaskolski.pro/wp-content/uploads/2009/12/GoogleAvatar64.png"><img class="alignleft size-full wp-image-291" title="GoogleAvatar64" src="http://blog.jaskolski.pro/wp-content/uploads/2009/12/GoogleAvatar64.png" alt="" width="64" height="64" /></a>No to się doczekaliśmy&#8230; Google odpaliło własną książkową machinę. Na dobry początek dostępne jest &#8211; bagatela &#8211; 3 mln tytułów. Dostępne niestety w US. Poza krainą Wuja Sama dostępne są publikacje z domeny publicznej. Jak pisze Google, negocjują z wydawcami.</p>
<p>Kolejny gracz na rynku, ciekawe czy w rzeczywistości taki otwarty jak mówi <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Zachęcam do zapoznania się z <a href="http://googleblog.blogspot.com/2010/12/discover-more-than-3-million-google.htm" onclick="pageTracker._trackPageview('/outgoing/googleblog.blogspot.com/2010/12/discover-more-than-3-million-google.htm?referer=');">notką na oficjalnym blogu Googla</a>, oraz do odwiedzenia samej <a href="http://books.google.com/ebooks" onclick="pageTracker._trackPageview('/outgoing/books.google.com/ebooks?referer=');">księgarni</a>.</p>
</div>
<div class="shr-publisher-509"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.jaskolski.pro/2010/12/07/google-ebooks-wystartowalo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Konferencja DevDay Łódź 2010</title>
		<link>http://blog.jaskolski.pro/2010/11/26/konferencja-devday-lodz-2010/</link>
		<comments>http://blog.jaskolski.pro/2010/11/26/konferencja-devday-lodz-2010/#comments</comments>
		<pubDate>Fri, 26 Nov 2010 08:29:58 +0000</pubDate>
		<dc:creator>Michał Jaskólski</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Świat realny]]></category>
		<category><![CDATA[Technologia]]></category>
		<category><![CDATA[Wydarzenia]]></category>
		<category><![CDATA[devday]]></category>
		<category><![CDATA[konferencja]]></category>

		<guid isPermaLink="false">http://blog.jaskolski.pro/?p=505</guid>
		<description><![CDATA[W imieniu swoim i Łódzkiej Grupy Profesjonalistów IT &#38; .NET oraz sponsorów mam zaszczyt zaprosić Was na konferencję DevDay, która odbędzie się 4. grudnia 2010 w Arterionie przy ul. Rewolucji 1905r. 82. Przygotowaliśmy dla Was kilka interesujących sesji oraz konkurs, &#8230; <a href="http://blog.jaskolski.pro/2010/11/26/konferencja-devday-lodz-2010/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p><a href="http://blog.jaskolski.pro/wp-content/uploads/2010/11/logo.png"><img class="alignleft size-thumbnail wp-image-506" title="DevDay" src="http://blog.jaskolski.pro/wp-content/uploads/2010/11/logo-150x90.png" alt="" width="150" height="90" /></a></p>
<p>W imieniu swoim i Łódzkiej Grupy Profesjonalistów IT &amp; .NET oraz sponsorów mam zaszczyt zaprosić Was na konferencję DevDay, która odbędzie się 4. grudnia 2010 w Arterionie przy ul. Rewolucji 1905r. 82.</p>
<p>Przygotowaliśmy dla Was kilka interesujących sesji oraz konkurs, w którym można wygrać nowiutkiego Xbox&#8217;a z Kinectem <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Zapraszam <a href="http://www.devday.pl" onclick="pageTracker._trackPageview('/outgoing/www.devday.pl?referer=');">na stronę konferencji</a>, gdzie możecie zapoznać się ze szczegółami oraz zarejestrować się na wydarzenie.</p>
<p>Dodatkowo zachęcam do odwiedzenia strony konferencji na <a href="http://www.facebook.com/pages/DevDay/160104230691793" onclick="pageTracker._trackPageview('/outgoing/www.facebook.com/pages/DevDay/160104230691793?referer=');">Facebooku </a> <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="shr-publisher-505"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.jaskolski.pro/2010/11/26/konferencja-devday-lodz-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IT na miękko</title>
		<link>http://blog.jaskolski.pro/2010/10/18/it-na-miekko/</link>
		<comments>http://blog.jaskolski.pro/2010/10/18/it-na-miekko/#comments</comments>
		<pubDate>Mon, 18 Oct 2010 12:02:36 +0000</pubDate>
		<dc:creator>Michał Jaskólski</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[spotkania]]></category>

		<guid isPermaLink="false">http://blog.jaskolski.pro/?p=501</guid>
		<description><![CDATA[Już w najbliższy czwartek 21 października 2010 odbędzie się kolejne spotkanie Łódzkiej Grupy Profesjonalistów IT &#38; .NET. Tym razem czeka nas spotkanie wyjątkowe, gdyż ani jedna sesja nie będzie sesją techniczną. Zaplanowaliśmy dla Was dwie sesje z gatunku miękkich. Obie &#8230; <a href="http://blog.jaskolski.pro/2010/10/18/it-na-miekko/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p><a href="http://blog.jaskolski.pro/wp-content/uploads/2010/10/GrupaLodzLogoSmall.png"><img class="alignleft size-full wp-image-502" title="GrupaLodzLogoSmall" src="http://blog.jaskolski.pro/wp-content/uploads/2010/10/GrupaLodzLogoSmall.png" alt="" width="200" height="32" /></a>Już w najbliższy czwartek 21 października 2010 odbędzie się kolejne spotkanie Łódzkiej Grupy Profesjonalistów IT &amp; .NET. Tym razem czeka nas spotkanie wyjątkowe, gdyż ani jedna sesja nie będzie sesją techniczną.</p>
<p>Zaplanowaliśmy dla Was dwie sesje z gatunku miękkich. Obie jednak skierowane są dla środowiska IT. Dzięki uprzejmości <strong>Sandry Rogalskiej</strong> pracującej w firmie <strong>Modis Polska Sp. z.o.o.</strong> jako <strong>IT Recruiter</strong>, która poprowadzi dwie sesje (&#8222;<strong>Rozmowa kwalifikacyjna</strong>&#8221; oraz &#8222;<strong>Profesjonalne CV programisty/informatyka</strong>&#8222;) dowiemy się m.in:</p>
<ul>
<li>Jak przygotować się do rozmowy kwalifikacyjnej.</li>
<li>Jak poprowadzić profesjonalną autoprezentację.</li>
<li>Co to jest mowa ciała i jakie ma znaczenie.</li>
<li>Jak powinno wyglądać CV, co powinno zawierać, a czego nie warto w nim umieszczać.</li>
<li>Jakie błędy najczęściej popełniane są przy tworzeniu CV i jak ich unikać.</li>
<li>Jak tworzyć CV w odpowiedzi na konkretną ofertę.</li>
</ul>
<p>Zapraszam wszystkich serdecznie w dniu <strong>21 października 2010</strong> o godzinie <strong>18:00</strong> do <strong>Centrum Komputerowego ZETO</strong>. Przypominam, iż <strong>wymagana</strong> jest wcześniejsza <strong><a href="http://wss.pl/group-4/CalendareventList/1,19106.aspx" onclick="pageTracker._trackPageview('/outgoing/wss.pl/group-4/CalendareventList/1_19106.aspx?referer=');">rejestracja</a></strong><a href="http://wss.pl/group-4/CalendareventList/1,19106.aspx" onclick="pageTracker._trackPageview('/outgoing/wss.pl/group-4/CalendareventList/1_19106.aspx?referer=');"> </a>na spotkanie.</p>
<p>Do zobaczenia!</p>
<div class="shr-publisher-501"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.jaskolski.pro/2010/10/18/it-na-miekko/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jeszcze trochę o NoSQL</title>
		<link>http://blog.jaskolski.pro/2010/09/23/jeszcze-troche-o-nosql/</link>
		<comments>http://blog.jaskolski.pro/2010/09/23/jeszcze-troche-o-nosql/#comments</comments>
		<pubDate>Thu, 23 Sep 2010 13:24:03 +0000</pubDate>
		<dc:creator>Michał Jaskólski</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Bazy danych]]></category>
		<category><![CDATA[no-sql]]></category>

		<guid isPermaLink="false">http://blog.jaskolski.pro/?p=498</guid>
		<description><![CDATA[Temat poruszany kilkakrotnie, jednak teraz powrócił do mojej świadomości dzięki ciekawemu artykułowi na blogu Tadeusza Wójcika. Polecam lekturę &#8211; zwłaszcza ciekawe mogą być scenariusze użycia opisywanej MongoDB. Jak wspomina autor, nawet panie i panowie z CERN mieszali coś w oprogramowaniu LHC z użyciem MongoDB Brzmi &#8230; <a href="http://blog.jaskolski.pro/2010/09/23/jeszcze-troche-o-nosql/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><div>
<p><a href="http://blog.jaskolski.pro/wp-content/uploads/2010/09/nosql.png"><img class="alignleft size-full wp-image-499" title="nosql" src="http://blog.jaskolski.pro/wp-content/uploads/2010/09/nosql.png" alt="" width="100" height="59" /></a>Temat poruszany kilkakrotnie, jednak teraz powrócił do mojej świadomości dzięki ciekawemu <a href="http://codefather.pl/post/1169125314/no-sql-no-problem-czyli-mongodb-norm-i-net" onclick="pageTracker._trackPageview('/outgoing/codefather.pl/post/1169125314/no-sql-no-problem-czyli-mongodb-norm-i-net?referer=');">artykułowi</a> na blogu <a href="http://codefather.pl/" onclick="pageTracker._trackPageview('/outgoing/codefather.pl/?referer=');">Tadeusza Wójcika</a>. Polecam lekturę &#8211; zwłaszcza ciekawe mogą być <a href="http://www.mongodb.org/display/DOCS/Use+Cases" onclick="pageTracker._trackPageview('/outgoing/www.mongodb.org/display/DOCS/Use+Cases?referer=');">scenariusze użycia</a> opisywanej <a href="http://www.mongodb.org/" onclick="pageTracker._trackPageview('/outgoing/www.mongodb.org/?referer=');">MongoDB</a>. Jak wspomina autor, nawet panie i panowie z CERN <a href="http://blog.mongodb.org/post/660037122/holy-large-hadron-collider-batman" onclick="pageTracker._trackPageview('/outgoing/blog.mongodb.org/post/660037122/holy-large-hadron-collider-batman?referer=');">mieszali coś w oprogramowaniu LHC</a> z użyciem MongoDB <img src='http://blog.jaskolski.pro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Brzmi ciekawie.</p>
</div>
<div class="shr-publisher-498"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.jaskolski.pro/2010/09/23/jeszcze-troche-o-nosql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wolność dla konopi?</title>
		<link>http://blog.jaskolski.pro/2010/09/18/wolnosc-dla-konopi/</link>
		<comments>http://blog.jaskolski.pro/2010/09/18/wolnosc-dla-konopi/#comments</comments>
		<pubDate>Sat, 18 Sep 2010 15:38:26 +0000</pubDate>
		<dc:creator>Michał Jaskólski</dc:creator>
				<category><![CDATA[Świat realny]]></category>
		<category><![CDATA[konopia indyjska]]></category>
		<category><![CDATA[legalizacja]]></category>
		<category><![CDATA[marihuana]]></category>
		<category><![CDATA[opinie]]></category>
		<category><![CDATA[społeczeństwo]]></category>

		<guid isPermaLink="false">http://blog.jaskolski.pro/?p=493</guid>
		<description><![CDATA[Ostatnio trochę medialnego szumu powstało wokół Marszu Wyzwolenia Konopi jaki odbył się dziś w Warszawie. Pierwotnie pojawiła się w prasie (o ile dobrze pamiętam w Gazecie Wybiórczej) informacja, że władze Miasta Stołecznego Warszawy nie wydały zgody na organizację marszu, po &#8230; <a href="http://blog.jaskolski.pro/2010/09/18/wolnosc-dla-konopi/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p><a href="http://blog.jaskolski.pro/wp-content/uploads/2010/09/konopie-listek.jpg"><img class="alignleft size-full wp-image-494" title="Liść konopi indyjskiej" src="http://blog.jaskolski.pro/wp-content/uploads/2010/09/konopie-listek.jpg" alt="" width="128" height="128" /></a>Ostatnio trochę medialnego szumu powstało wokół Marszu Wyzwolenia Konopi jaki odbył się dziś w Warszawie. Pierwotnie pojawiła się w prasie (o ile dobrze pamiętam w Gazecie Wybiórczej) informacja, że władze Miasta Stołecznego Warszawy nie wydały zgody na organizację marszu, po czym marsz się odbył. Gdy usłyszałem o braku przyzwolenia do zorganizowania tego wydarzenia, pomyślałem &#8211; hipokryci (władze). No bo w czym taki marsz jest gorszy od Parady Równości dla przykładu? W wolnym kraju każdy ma prawo zamanifestować swoje poglądy (pomijając faszyzm, stalinizm i inne zabronione z uzasadnionych względów).</p>
<p><span id="more-493"></span>W ogóle dlaczego palących trawkę utożsamia się z ćpunami? W czym marihuana jest gorsza od alkoholu czy papierosów? Najprostsza odpowiedź jaka przychodzi mi do głowy &#8211; nie przynosi korzyści państwu. Wszak za papieroski i wódeczkę płacimy nie mało, z czego ogrom kwoty to akcyza, która trafia wprost do Skarbu Państwa. No a jak pieniążki płyną sobie wartkim strumieniem, to przecież nie może być to nic złego. Prawda? O ile więcej zła wyrządza alkohol, czy papierosy? A mimo tego są legalne? Ktoś powie: ale narkotyki uzależniają. Wszystko uzależnia, picie, palenie, seks, spacery, bieganie, adrenalina, wszystko. Uzależnić można się od wszystkiego, bo to jest kwestia ludzkiej psychiki. Można się uzależnić od jedzenia i czekolady; otyłość &#8211; jakie żniwo zbiera ta choroba co roku? Zawały, cukrzyca, niepełnosprawność&#8230; I co? Jakoś wolno jeść. Wolno pić i palić.</p>
<p>Sam nie palę ani papierosów, ani trawki. Znam jednak multum osób, które paliły lub palą nadal &#8211; każdy z nas zapewne zna. Nikt, dosłownie nikt jakoś się nie uzależnił. Nie uzależnił się w większym stopniu niż można się uzależnić od dobrej zabawy, dobrego drinka, kawałka czekolady czy dawki adrenaliny podczas sportowej rywalizacji.</p>
<p>Nie słychać, aby w krajach gdzie marihuana jest legalna, wszyscy obywatele leżeli w szpitalu na odwyku.</p>
<p>Uważam, że w czystej nie doprawionej chemiczne trawce nie ma nic złego. Nie dewastuje organizmu tak jak chemia, jak chociażby LEGALNE dopalacze.</p>
<p>Jeżeli już o dopalaczach mowa, to podstawowym błędem jaki został popełniony przez polskich ustawodawców jest istnienie czarnej listy substancji niedozwolonych. Ponieważ pomysłowość ludzka nie zna granic, co rusz na rynku będą pojawiać się kolejne chemikalia o działaniu psychoaktywnym. Czarna lista za tymi zmianami nie ma prawa nadążyć. Częściowym rozwiązaniem tego problemu jest zastąpienie czarnego białym, czyli wprowadzenie białej listy &#8211; listy substancji dozwolonych. Znacznie efektywniejsze i elastyczniejsze.</p>
<p>Ja osobiście jestem za wolnością jednostki, wolnością której granice stanowi wolność innych. Jeżeli ktoś ma ochotę truć się chemicznym świństwem &#8211; proszę bardzo. Jeżeli jest na tyle głupi, aby doprowadzić do samozagłady &#8211; nie widzę problemu. Dla podatników to też ulga. Jest jeden warunek &#8211; ktoś kto wybrał taką właśnie ścieżkę nie powinien być leczony z moich pieniędzy. Brakuje Ci rozsądku? Masz problem. Kropka. Owszem świat nie jest czarno-biały i każdy może zbłądzić, ale od tego ma się głowę na karku i innych ludzi wokół, aby się odnaleźć. Robienie z tego sprawy państwowej jest chyba skazane na niepowodzenie.</p>
<p>Może więc warto wprowadzić akcyzę i zalegalizować handel marihuaną. Przynajmniej będzie wiadomo, że pochodzi ze sprawdzonego źródła i nikt jej nie &#8222;ochrzcił&#8221; jakimś kwasem. A jeżeli ktoś nie umie poradzić sobie z samym sobą to równie dobrze może zniszczyć się alkoholem, który może kupić na każdym kroku&#8230;</p>
<div class="shr-publisher-493"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.jaskolski.pro/2010/09/18/wolnosc-dla-konopi/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Kilka drobnostek które sprawią, że będziecie kodować lepiej (w C#)</title>
		<link>http://blog.jaskolski.pro/2010/09/17/kilka-drobnostek-ktore-sprawia-ze-bedziecie-kodowac-lepiej-w-c/</link>
		<comments>http://blog.jaskolski.pro/2010/09/17/kilka-drobnostek-ktore-sprawia-ze-bedziecie-kodowac-lepiej-w-c/#comments</comments>
		<pubDate>Fri, 17 Sep 2010 07:36:54 +0000</pubDate>
		<dc:creator>Michał Jaskólski</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[c#]]></category>

		<guid isPermaLink="false">http://blog.jaskolski.pro/?p=490</guid>
		<description><![CDATA[Tym razem chciałbym zwrócić Waszą uwagę na serię artykułów autorstwa Jammes&#8217;a Michael&#8217;a, w których opisuje kilka cech języka C#, które sprawią, że będziecie kodować czytelniej i efektywniej. Zachęcam wszystkich do lektury. Cykl składa się z trzech części: C#/.NET Five Little &#8230; <a href="http://blog.jaskolski.pro/2010/09/17/kilka-drobnostek-ktore-sprawia-ze-bedziecie-kodowac-lepiej-w-c/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p><a href="http://blog.jaskolski.pro/wp-content/uploads/2010/02/VisualStudio2010Icon.png"><img class="alignleft size-full wp-image-403" title="Visual Studio 2010" src="http://blog.jaskolski.pro/wp-content/uploads/2010/02/VisualStudio2010Icon.png" alt="" width="57" height="34" /></a>Tym razem chciałbym zwrócić Waszą uwagę na serię artykułów autorstwa <a href="http://geekswithblogs.net/BlackRabbitCoder/Default.aspx" onclick="pageTracker._trackPageview('/outgoing/geekswithblogs.net/BlackRabbitCoder/Default.aspx?referer=');">Jammes&#8217;a Michael&#8217;a</a>, w których opisuje kilka cech języka C#, które sprawią, że będziecie kodować czytelniej i efektywniej. Zachęcam wszystkich do lektury.</p>
<p>Cykl składa się z trzech części:</p>
<ul>
<li><a href="http://geekswithblogs.net/BlackRabbitCoder/archive/2010/08/26/c.net-five-little-wonders-that-make-code-better-1-of.aspx" onclick="pageTracker._trackPageview('/outgoing/geekswithblogs.net/BlackRabbitCoder/archive/2010/08/26/c.net-five-little-wonders-that-make-code-better-1-of.aspx?referer=');">C#/.NET Five Little Wonders That Make Code Better (1 of 3)</a></li>
<li><a href="http://geekswithblogs.net/BlackRabbitCoder/archive/2010/09/02/c.net-five-more-little-wonders-that-make-code-better-2.aspx" onclick="pageTracker._trackPageview('/outgoing/geekswithblogs.net/BlackRabbitCoder/archive/2010/09/02/c.net-five-more-little-wonders-that-make-code-better-2.aspx?referer=');">C#/.NET Five Little Wonders That Make Code Better (2 of 3)</a></li>
<li><a href="http://geekswithblogs.net/BlackRabbitCoder/archive/2010/09/09/c.net-five-final-little-wonders-that-make-code-better-3.aspx" onclick="pageTracker._trackPageview('/outgoing/geekswithblogs.net/BlackRabbitCoder/archive/2010/09/09/c.net-five-final-little-wonders-that-make-code-better-3.aspx?referer=');">C#/.NET Five Little Wonders That Make Code Better (3 of 3)</a></li>
</ul>
<div class="shr-publisher-490"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.jaskolski.pro/2010/09/17/kilka-drobnostek-ktore-sprawia-ze-bedziecie-kodowac-lepiej-w-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

