<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://zine.net.pl/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Ww.CodeSculptor</title><subtitle type="html" /><id>http://zine.net.pl/blogs/windywinter/atom.aspx</id><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/default.aspx" /><link rel="self" type="application/atom+xml" href="http://zine.net.pl/blogs/windywinter/atom.aspx" /><generator uri="http://communityserver.org" version="2.1.61129.2">Community Server</generator><updated>2007-01-28T16:23:00Z</updated><entry><title>Moze jest tu cos fajnego</title><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/archive/2008/11/21/moze-jest-tu-cos-fajnego.aspx" /><id>http://zine.net.pl/blogs/windywinter/archive/2008/11/21/moze-jest-tu-cos-fajnego.aspx</id><published>2008-11-21T10:18:00Z</published><updated>2008-11-21T10:18:00Z</updated><content type="html">&lt;P&gt;W nawiązaniu do postu &lt;A href="http://zine.net.pl/blogs/gutek/archive/2008/11/21/co-si-zbli-a-co-fajnego.aspx"&gt;Jakuba&lt;/A&gt;, podejmując tę zabawe, chciałem oznajmić że:&lt;/P&gt;
&lt;P&gt;Może coś napisze dziś, a może jutro, a może później. Nie żeby to pewnie kogoś zainteresowało, ale "kolorytu"&lt;SUP&gt;*)&lt;/SUP&gt; doda&lt;/P&gt;
&lt;P&gt;;-)&lt;/P&gt;
&lt;P&gt;&lt;SUP&gt;*)&lt;/SUP&gt;&amp;nbsp;To sympatyczne określenie zaczerpnięte od Michała Grzegorzewskiego. Michał! dołącz się do kolorowania... Więc chodź pomaluj&amp;nbsp;nasz świat/Na żółto i na niebiesko...&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=2454" width="1" height="1"&gt;</content><author><name>Wojciech Gebczyk</name><uri>http://zine.net.pl/members/Wojciech+Gebczyk.aspx</uri></author></entry><entry><title>Zadanie - Komunikacja klient-serwer</title><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/archive/2008/10/27/zadanie-komunikacja-klient-serwer.aspx" /><id>http://zine.net.pl/blogs/windywinter/archive/2008/10/27/zadanie-komunikacja-klient-serwer.aspx</id><published>2008-10-27T08:21:00Z</published><updated>2008-10-27T08:21:00Z</updated><content type="html">&lt;P&gt;Arek próbuje zacząć bardziej praktyczne podejście do tematów omawianych na wg.net. Jako ze pomysł mi się podoba, to może teraz ja opisze pewien problem na który się natknąłem.&lt;/P&gt;
&lt;H4&gt;Problem&lt;/H4&gt;
&lt;P&gt;Mamy układ klient-serwer z komunikacja po TCP/IP. Czyli serwer otwiera gniazdko (Socket lub TcpListener), klient łączy się, następuje wymiana wiadomości i klient się rozłącza. A teraz więcej szczegółów.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Wiadomość to poprawny dokument XML, można założyć na potrzeby tego przykładu ze to tylko znaki ASCII wiec mapowanie wiadomość ciąg bajtów jest trywialne.&lt;/LI&gt;
&lt;LI&gt;Wymiana wiadomości przebiega tak ze klient wysyła wiadomość do serwera i zaczyna słuchać odpowiedzi. Potem wysyła kolejna wiadomość i nasłuchuje odpowiedzi.&lt;/LI&gt;
&lt;LI&gt;Serwer robi to samo tylko symetrycznie. Najpierw przyjmuje połączenie, potem wczytuje wiadomość od klienta.&lt;/LI&gt;
&lt;LI&gt;Generuje odpowiedz i ja wysyła. Potem znowu nasłuchuje wiadomości od klienta lub końca połączenia.&lt;/LI&gt;
&lt;LI&gt;Serwer oczekuje przy odbiorze tylko bajów wiadomości i sam wysyła tylko bajty wiadomości-odpowiedzi.&lt;/LI&gt;&lt;/OL&gt;
&lt;H4&gt;Zadanie&lt;/H4&gt;
&lt;P&gt;Jak wydajnie/sprytnie/prosto zaimplementować cześć kliencka? Chodzi o takie rozwiązaniem, które niekoniecznie będzie jak najbardziej niskopoziomowe, lecz proste i łatwo utrzymywane. Można użyć Socket czy TcpClient. Niech w tym rozwiązaniu szybkość wymiany informacji raczej będzie limitowana ograniczeniami fizycznymi sieci niż jakimś skomplikowanym przetwarzaniem informacji z sieci przez klienta.&lt;/P&gt;
&lt;H4&gt;Uwagi&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Implementacja serwera jest stała i nie można jej zmieniać.&lt;/LI&gt;
&lt;LI&gt;Przykładowa implementacja serwera może być taka ze generuje losowa wiadomość jako odpowiedz o długości od 200 B do 8 kB.&lt;/LI&gt;
&lt;LI&gt;Należy oczekiwać ze czasami (powiedzmy 10%) sytuacji będą opóźnienia na sieci kilkunastu/kilkudziesięciu milisekundowe, czasami parę sekund.&lt;/LI&gt;
&lt;LI&gt;Pytania proszę zadawać w komentarzach.&lt;/LI&gt;&lt;/OL&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=2293" width="1" height="1"&gt;</content><author><name>Wojciech Gebczyk</name><uri>http://zine.net.pl/members/Wojciech+Gebczyk.aspx</uri></author></entry><entry><title>Podręczne szyfrowanie danych w .NET</title><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/archive/2008/10/21/podr-czne-szyfrowanie-danych-w-net.aspx" /><link rel="enclosure" type="application/x-zip-compressed" length="33738" href="http://zine.net.pl/blogs/windywinter/attachment/2264.ashx" /><id>http://zine.net.pl/blogs/windywinter/archive/2008/10/21/podr-czne-szyfrowanie-danych-w-net.aspx</id><published>2008-10-21T14:47:00Z</published><updated>2008-10-21T14:47:00Z</updated><content type="html">&lt;P&gt;Ten tekst powstał w nawiązaniu do artykułu &lt;A href="http://zine.net.pl/blogs/mgrzeg/"&gt;Michała Grzegorzewskiego&lt;/A&gt; [&lt;A href="http://zine.net.pl/blogs/mgrzeg/archive/2008/10/16/retrieve-services-user-account-password.aspx"&gt;Zabawy z LSA - wydłubywanie haseł usług&lt;/A&gt;] oraz Jego nawoływaniu do napisania czegoś o ProtectedData i ProtectedMemory.&lt;/P&gt;
&lt;H3&gt;ProtectedData&lt;/H3&gt;
&lt;P&gt;Wyobraźmy sobie scenariusz gdzie posiadamy ekran logowania wraz z opcją zapamiętania hasła użytkownika. Opcja zapamiętywania służy temu głównie, aby użytkownikowi opcjonalnie sugerować jego hasło gdy działa głównie na jednej stacji roboczej. Zazwyczaj przecież jest tak, że pracujemy w domu czy pracy na jednej maszynie która jest nawet przypisana do nas jako część stanowiska pracy.&lt;/P&gt;
&lt;H4&gt;Akt 1&lt;/H4&gt;
&lt;P&gt;Przykład ten ilustruje projekt &lt;STRONG&gt;ZineNet.DataProtection.Act1&lt;/STRONG&gt;. Podczas uruchamiania aplikacji użytkownik wpisuje nazwę użytkownika oraz hasło i zaznacza/odznacza opcję "zapamiętaj hasło". Hasło zapisywane jest w jeden z typowych sposobów dla aplikacji .NET, czyli ustawieniach użytkownika &lt;STRONG&gt;Properties/Settings.settings&lt;/STRONG&gt;. Przy kolejnej autentykacji hasło jest już wpisane i tylko użytkownik wpisuje nazwę i wciska "Enter". Co za &lt;EM&gt;user experience&lt;/EM&gt;! Przecież nikt nie lubi zapamiętywać haseł!&lt;/P&gt;
&lt;P&gt;Zajrzyjmy teraz co stało się z zapamiętaną wartością hasła. Plik konfiguracji uzytkownika możemy w naszym przypadku znaleźć w katalogu profilu użytkownika, coś mniej więcej:&lt;BR&gt;&lt;STRONG&gt;Local Settings\Application Data\ZineNet\ZineNet.DataProtection.cos_tam\1.0.1.0\user.config&lt;/STRONG&gt;. Zaglądamy do środka i tu rozczarowujący widok. Hasło przechowywane jest w czystej postaci, jak go użytkownik stworzył.&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;lt;configuration&amp;gt;&lt;BR&gt;...&lt;BR&gt;&amp;nbsp; &amp;lt;userSettings&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ZineNet.DataProtection.Act1.Properties.Settings&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;setting name="Logon_Password" serializeAs="String"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;bbb&amp;lt;/value&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/setting&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ZineNet.DataProtection.Act1.Properties.Settings&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/userSettings&amp;gt;&lt;BR&gt;&amp;lt;/configuration&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;H4&gt;Akt 2&lt;/H4&gt;
&lt;P&gt;Taki sposób to dość marne zabezpieczenie, więc postaramy się teraz to naprawić. Najpierw zmieniamy typ zapamiętywanego hasła z System.String na System.Byte[] (i najlepiej nazwę wpisu ustawień użytkownika na wypadek kolizji i problemów z wersjonowaniem naszej aplikacji). W kolejnym kroku zamiast zapisywać hasło w czystej postaci jak poniżej:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; (_rememberPassword) {&lt;br /&gt;  Properties.Settings.Default.Logon_Password &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; password;&lt;br /&gt;  Properties.Settings.Default.Save();&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Zapiszemy ją jako zaszyfrowany ciąg bajtów. Szyfrowanie możemy uzyskać za pomocą metody "ProtectedData.Protect(...)". Klasa ProtectedData ta faktycznie opakowuje funkcje systemowe DPAPI: CryptProtectData i CryptUnprotectData. Metoda Protect przyjmuje 3 parametry i zwraca ciąg bajtów, którym jest zaszyfrowany ciąg bajtów wejściowych.&lt;/P&gt;
&lt;P&gt;Pierwszym parametrem jest "userData". Jest to ciąg bajtów dowolnej długości, który należy zaszyfrować.&lt;/P&gt;
&lt;P&gt;Drugim parametrem jest "optionalEntropy". Jest to kolejny ciąg bajtów (może być innego rozmiaru niż userData) który zawiera losowe wartości wzmacniające szyfrowane dane. Idea jest taka sama jak z szyfrowaniem haseł i tak zwanym "ziarnem" (&lt;A href="http://en.wikipedia.org/wiki/Salt_(cryptography"&gt;http://en.wikipedia.org/wiki/Salt_(cryptography&lt;/A&gt;)).&lt;/P&gt;
&lt;P&gt;Trzeci parametr "scope" definiuje na jakim poziomie dane powinny być zabezpieczone. Możemy wybrać opcję szyfrowania w ramach konta użytkownika (wtedy tylko w kontekście tego samego użytkownika będzie można te dane odszyfrować) lub w ramach całej maszyny.&lt;/P&gt;
&lt;P&gt;Poziom szyfrowania "maszyna" może być użyteczny na przykład to przechowywania haseł do serwera bazy danych, jeśli ten sam serwer jest używany przez wielu użytkowników z tej samej maszyny. Po prostu zaszyfrowane dane będzie mógł odszyfrować każdy, kto zaloguje się poprawnie do komputera.&lt;/P&gt;
&lt;P&gt;W naszym przypadku pomijam opcjonalna wartość entropii i ustawiam poziom "użytkownika". Dzięki temu na tej samej maszynie różne osoby (konta) będą mogły używać naszej aplikacji nie przeszkadzając sobie.&lt;/P&gt;
&lt;P&gt;Drugim krokiem jest zmiana uzyskiwania hasła już zapisanego dla kolejnych uruchomień aplikacji. Zamiast prostego:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;_password &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; Properties.Settings.Default.Logon_Password ?? &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;""&lt;/span&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Musimy użyć metody "ProtectedData.Unprotect(...)" w następujący sposób:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;var encPassword &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; Properties.Settings.Default.Logon_PasswordEnc;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; (encPassword !&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;null&lt;/span&gt;) {&lt;br /&gt;  _password &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; Encoding.Unicode.GetString(ProtectedData.Unprotect(encPassword, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;null&lt;/span&gt;, DataProtectionScope.CurrentUser));&lt;br /&gt;} &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;else&lt;/span&gt; {&lt;br /&gt;  _password &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;""&lt;/span&gt;;&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Metoda Unprotect przyjmuje 3 parametry jak metoda Protect, z tym wyjątkiem że pierwszy parametr jest zaszyfrowanym ciągiem bajtów uzyskanym z wcześniejszego użycia metody Protect. Jeśli używamy opcjonalnej entropii, to musimy jako drugi parametr przekazać tą samą wartość której użyliśmy przy metodzie Protect. Poniższy pseudo kod ilustruje wymaganą zależność:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;var data = ...&lt;BR&gt;var entropy = ...&lt;BR&gt;var scope = ...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;var enc = Protect(data, entropy, scope&lt;BR&gt;var data2 = Unprotect(enc, entropy, scope)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;assert(data == data2)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Zaglądamy ponownie do pliku user.config tym razem w katalogu &lt;STRONG&gt;Local Settings\Application Data\ZineNet\ZineNet.DataProtection.cos_tam\1.0.2.0\user.config&lt;/STRONG&gt; i widzimy tym razem coś o wiele porządniejszego:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;lt;configuration&amp;gt;&lt;BR&gt;...&lt;BR&gt;&amp;nbsp; &amp;lt;userSettings&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ZineNet.DataProtection.Act2.Properties.Settings&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;setting name="Logon_PasswordEnc" serializeAs="Xml"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;base64Binary&amp;gt;AQAAANCMnd8BFdERjHoAwE...&amp;lt;/base64Binary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/value&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/setting&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ZineNet.DataProtection.Act2.Properties.Settings&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/userSettings&amp;gt;&lt;BR&gt;&amp;lt;/configuration&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Gotową aplikację, a dokładniej jej projekt można znaleźć w załączonych plikach do artykułu pod nazwą &lt;STRONG&gt;ZineNet.DataProtection.Act2&lt;/STRONG&gt;&lt;/P&gt;
&lt;H3&gt;ProtectedMemory&lt;/H3&gt;
&lt;P&gt;Podobne działanie jak ProtectedData mają metody klasy ProtectedMemory. Są&amp;nbsp;trzy zasadnicze różnice.&lt;/P&gt;
&lt;P&gt;Pierwszą jest to że metody ProtectedMemory opakowują metody DPAPI CryptProtectMemory i CryptUnprotectMemory i jako takie nie przyjmują już opcjonalnej wartości entropii.&lt;/P&gt;
&lt;P&gt;Drugą różnicą jest inny typ enumeracji dla parametru &lt;EM&gt;scope&lt;/EM&gt;. Możemy wybrać opcję szyfrowania wewnątrz procesową, między procesową oraz w ramach kontekstu użytkownika.&lt;/P&gt;
&lt;P&gt;Trzecią&amp;nbsp;różnicą jest to, że możemy szyfrować i deszyfrować w ramach jednego uruchomienia maszyny. Restart komputera wymazuje informacje o tym jak zdeszyfrować poprzednio szyfrowane dane. Typowym zastosowaniem jest szyfrowanie tych danych, które są ścisłe sesyjne, czy muszą istnieć tylko podczas działania aplikacji i nie są nigdzie zapisywane.&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=2264" width="1" height="1"&gt;</content><author><name>Wojciech Gebczyk</name><uri>http://zine.net.pl/members/Wojciech+Gebczyk.aspx</uri></author></entry><entry><title>Zagadka 1 - Jak to jest możliwe?</title><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/archive/2008/09/08/zagadka-1-jak-to-jest-mo-liwe.aspx" /><id>http://zine.net.pl/blogs/windywinter/archive/2008/09/08/zagadka-1-jak-to-jest-mo-liwe.aspx</id><published>2008-09-08T10:05:00Z</published><updated>2008-09-08T10:05:00Z</updated><content type="html">&lt;P&gt;Przegladajac poranna dawke postow na blogach (nieodlaczny Google Reader), natknalem sie na ciekawy i zaskakujacy fragmetn kodu. Zaczalem doglebniej przegladac siec i swoje zasoby dyskowe i moje zaskoczenie roslo jeszcze bardziej. Dosc gadaniny zapraszam do rozwiazania zagadki (raczej nie przewiduje nagrod). Niestety ta zagadka ma jeden feler (ktory sam nie znosze) - dobra odpowiedzia jest ta ktora mam na mysli. Czyli jest to raczej proba zainteresowania ciekawym zjawiskiem jezyke C# niz prawdziwa zagadka.&lt;/P&gt;
&lt;P&gt;Ponizej jest fragment kody C#. Z pewnego typu wycialem kod konstruktora i pola. Pytanie: Jak to jest mozliwe?&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;readonly&lt;/span&gt; Aaa Empty;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; Aaa(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; x, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; y) {&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;this&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; Empty;&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;"Jak" znaczy wskazac odpowiedni fragment&amp;nbsp;specyfikacji&amp;nbsp;języka C#.&lt;/P&gt;
&lt;P&gt;EDIT: Poprawna odpowiedz dal "apl". Gratulacje!&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;struct&lt;/span&gt; MyStruct {&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;readonly&lt;/span&gt; MyStruct Empty;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; _x;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; MyStruct(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;bool&lt;/span&gt; notUsed) {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;this&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; Empty;&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Warto w tym momencie przytoczyc fragment dokumentacji C# 3 dotyczacy slowa kluczowego this w kontekscie klasy i struktury:&lt;/P&gt;
&lt;P&gt;Klasa:&lt;/P&gt;
&lt;P&gt;"When this is used in a primary-expression within an instance constructor of a class , it is classified as a value. The type of the value is the instance type (§10.3.1) of the class within which the usage occurs, and the value is a reference to the object being constructed."&lt;/P&gt;
&lt;P&gt;Struktura:&lt;/P&gt;
&lt;P&gt;"When this is used in a primary-expression within an instance constructor of a struct, it is classified as a variable. The type of the variable is the instance type (§10.3.1) of the struct within which the usage occurs, and the variable represents the struct being constructed. The this variable of an instance constructor of a struct behaves exactly the same as an out parameter of the struct type—in particular, this means that the variable must be definitely assigned in every execution path of the instance constructor."&lt;/P&gt;
&lt;P&gt;Z pierwszego zdania w obu tekstach widac ze sa traktowane inaczej w klasie i strukturze. Dodatkowo z tego co z rozumialme z reszty wyjasnienia dla struktury, to "value" nalezy traktowac jak parameter out (nalezy zainicjalizowac out-parametr przed opuszczeniem metody), czyli cos w rodzaju:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;struct&lt;/span&gt; MyStruct {&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; MyStruct(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;out&lt;/span&gt; MyStruct &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;this&lt;/span&gt;) {&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Lecz porownujac&amp;nbsp;prawdziwy parametr "out" i ten pseudo, wychodza na jaw znaczace roznice:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;struct&lt;/span&gt; MyStruct {&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; _x;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; MyStruct(&lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;/* out int this, */&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; x) {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;this&lt;/span&gt;._x &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; x;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;class&lt;/span&gt; MyClass {&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; _x;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;void&lt;/span&gt; MyClassMethod(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;out&lt;/span&gt; MyClass @&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;this&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; x) {&lt;br /&gt;        @&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;this&lt;/span&gt;._x &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; x;&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;W drugim przypadku dostaniemy blad kompilacji "error CS0269: Use of unassigned out parameter 'this'" dla linii "@this._x = x;".&lt;/P&gt;
&lt;P&gt;Podgladajac kod IL wygenerowany dla roznych przypadkow, dochodze do wniosku, ze konstrukcja "this =" sluzy poprostu za inicjalizator struktury zap omoca wartosci po prawej stronie znaku rownosci konstrukcji "this =". Inicjalizator w sensie "memcpy" - czyli tak jak dziala przypisanie struktur jezyka C# - kopiujac wartosca nie przypisujac referencje.&lt;/P&gt;
&lt;P&gt;Podsumowujac, przegladajac blogi i czytajac kod (w tym przypadku MEF Preview 2), czasami mozna czegos nowego sie nauczyc ( a dokumentacje C# poprawic ;-) ).&lt;/P&gt;
&lt;P&gt;BTW: Wyglada jak by w .NET 4, proste pojemniki na dane (takie jak opisywalem w &lt;A href="http://zine.net.pl/blogs/windywinter/archive/2008/07/21/ww-vs-szablony-tekstowe-w-vs2008.aspx"&gt;jednym z tekstow&lt;/A&gt;) beda dostepne "z pudelka"!&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1961" width="1" height="1"&gt;</content><author><name>Wojciech Gebczyk</name><uri>http://zine.net.pl/members/Wojciech+Gebczyk.aspx</uri></author></entry><entry><title>[Ww.Misc] Resharper 4.1 i dalej</title><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/archive/2008/08/29/ww-misc-resharper-4-1-i-dalej.aspx" /><id>http://zine.net.pl/blogs/windywinter/archive/2008/08/29/ww-misc-resharper-4-1-i-dalej.aspx</id><published>2008-08-29T10:18:00Z</published><updated>2008-08-29T10:18:00Z</updated><content type="html">&lt;P&gt;Zapewne dzis (2008-08-29) lub najdalej w poniedzialek wyjdzie wersja 4.1 (4.0.1) swietnego narzedzia Resharper. Nie jest to oficjalna wiadomosc, jako ze nie ma tego do sciagniecia czy na oficjalnych blogach, lecz bugi dla wersji 4.1 zostaly oznaczone jako "Release Date: 29 Aug 08" (&lt;A href="http://www.jetbrains.net/jira/browse/RSRP/fixforversion/11620"&gt;http://www.jetbrains.net/jira/browse/RSRP/fixforversion/11620&lt;/A&gt;), od dluzszego casu coraz rzadziej sa publikowne nowe buildy no i mozna zauwazyc ze 4.5 pojawilo sie w ichniej "bugzilli". Ponizej pare luznych uawg, mysli na temat R#.&lt;/P&gt;
&lt;H5&gt;Narzedzie&lt;/H5&gt;
&lt;P&gt;Ogolnie jest to najlepsze narzedzie wspierajace VS z jakim moglem pracowac. Naprawde w codzeinnej pracy pomaga mi znacznie.&amp;nbsp;Do mniej "slodkich" uwag dodalbym wysokie wymagania pamieciowe i sporo trzeba poswiecic na konfiguracje aby uzywanie R# bylo intuicyjne (co nie znaczy nie mozliwe). Cos za cos - ja nadal uwazam ze wady sa calkowiecie zrekompensowane przez zalety tego narzedzia&lt;/P&gt;
&lt;H5&gt;Support&lt;/H5&gt;
&lt;P&gt;Tu, juz nie jest tak rozowo. Jedynym widocznym plusem jest automatyczne raportowanie bledow po wystapienu. W czasach wersji 1.x czy 2 druzyna R# byla bardziej sklonna uznawac zgloszone uwagi/problemy jako bugi. Niestety podzcas ostatnich wersji, pod uwage brane sa uwagi krytyczne (wykladanie VS, czy blokowanie VS), pozostale zazwyczaj koncza w szufladce "w nastepnej wersji" albo "won't fix".&lt;/P&gt;
&lt;H5&gt;Release&lt;/H5&gt;
&lt;P&gt;Wersja 4.x produkowana byla naprawde&amp;nbsp; dlugo! Prezkroczono obiecywane terminy 2-3 krotnie. Instalowalem "Nightly Builds" w miare regularnie (pewnie tak &amp;gt;80% opublikowanych buildow zainstalowalem) i w miare regularnie przegladalem stan "buzgilli" tego projektu. Zauwazylem jedna ciekawa rzecz. A mianowicie przed opublikowaniem wersji 4.0 mieli kilka(nascie) blockerow i kilkadzeisiat criticali (chyba bylo kolo 80 albo odrobine ponad 100 - dokladnie nie pamietam), lecz mimo to produkt wypuscili! Zapewne niezadoloenie w "comunity" z niewypuszczanie RTM mialo swoj udzial w szybkiej publikacji, lecz chyba troche zbyt pochopnie. Zadziwiajaca rzecz stala sie pare dni po publikacji - bugi zostaly przerzucone do wersji 4.0.1 (chyba to sie nazywalo jeszcze wersja 4.0.1, bo ostatnio ma to nazwe 4.1). Wywnioskowac z tego mozna ze wersja 4.0 byla uznana arbitralnie (aby zatkac usta niezadolonym)&amp;nbsp;a prace trwaly nadal.&lt;/P&gt;
&lt;P&gt;Zadziwiajaca sytuacje obserwuje ponownie. Pojawi sie wersja 4.1 i juz bugi sa przerzucane do 4.5 lub dalej. W tej chwili zdecydowana wiekszosc bugow przerzucili do 4.5. Chyba maja skrypt jakis w stylu "Dodaj nowa wersje i przerzuc wszystkie zgnilki.cmd" ;-)&lt;/P&gt;
&lt;H5&gt;Szczotka + Zmiotka&lt;/H5&gt;
&lt;P&gt;Nie podoba mi sie sytuacje, gdzie w wersji X zgloszony jest problem (nie jeden i nie dwa!) klasyfikowany jako powazny i nic sie z nim nie dzieje przez kolejnych kilka wersji. Sukcesywnie jest przerzucany z wersji do wersji. Uwazam ze powinni sie zdecydowac na "won't fix" (bo taka maja wizje produktu), badz rozwiazac go bez nieskonczonego przesuwania. A'propo takiego zwodzenia, przypomina mi sie sytuacja gdzie kupilem licencje na ktoras wersji, powodowany tym ze rozwiazany zostanie pewien powazny dla mnie problem. mial byc rozwiazany tuz po pierwszym oficjalnym release i nawet tak byl oznaczony w "bugzilli". Niestaty pomimo tego oznaczenia i zapewnien ze strony "kogos w supporcie", to sie nie stalo. Krotko mowiac zostalem oszukany. Jakos mam wrazenie ze podobnie dzieje sie teraz z tym przesuwaniem bugow z wersji na wersje...&lt;/P&gt;
&lt;H5&gt;Wersja 4.5&lt;/H5&gt;
&lt;P&gt;Pomimo tych wszelkich "dziwactw" teamu R#, ciekaw jestem jakie nowosci zaproponuja w nowej, ulamkowej wersji. Trudno cos zgadywac, jako ze aktualnie jest dosc pelnym produktem. Moze ktos z Was ma jakis pomys/przepowiednie?&lt;/P&gt;
&lt;H5&gt;...&lt;/H5&gt;
&lt;P&gt;Pomimo ze nie podoba mi sie sposob dzialania Supportu R#, na pewno nastepna wersje bede uzywal, lecz przy kolejnym uaktualnieniu dobrze sie zastanowie. Kto wie, moze jakies nowe narzedzie sie pojawi...&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1853" width="1" height="1"&gt;</content><author><name>Wojciech Gebczyk</name><uri>http://zine.net.pl/members/Wojciech+Gebczyk.aspx</uri></author><category term="Text" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Text/default.aspx" /><category term="Resharper" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Resharper/default.aspx" /></entry><entry><title>[Ww.Note] Male przyspieszacze czasu</title><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/archive/2008/08/22/ww-note-male-przyspieszacze-czasu.aspx" /><id>http://zine.net.pl/blogs/windywinter/archive/2008/08/22/ww-note-male-przyspieszacze-czasu.aspx</id><published>2008-08-22T11:14:00Z</published><updated>2008-08-22T11:14:00Z</updated><content type="html">&lt;P&gt;Chcialbym sie podzielic malymi fragmentami kodu, bedacymi przspieszaczami czasu. Podobny &lt;A href="http://zine.net.pl/blogs/procent/archive/2008/08/02/przydatne-przyk-ady-c-3-0.aspx"&gt;tekst&lt;/A&gt; opublikowal &lt;A href="http://zine.net.pl/blogs/procent/default.aspx"&gt;Maciej Aniserowicz&lt;/A&gt;. Przykłady dotycza generowania obiektow string z roznego rodzaju powtorzeniami oraz prawie powtorzeniami.&lt;/P&gt;
&lt;H5&gt;1. Wygenerowanie tekstu ze zbioru napisow poprzedzielanych jakims delimiterem.&lt;/H5&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;{&lt;br /&gt;    var arr &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt;[] { &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"ala"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"ma"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"kota"&lt;/span&gt; };&lt;br /&gt;    var s &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; String.Join(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;" "&lt;/span&gt;, arr);&lt;br /&gt;    &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;// s == "ala ma kota"&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;{&lt;br /&gt;    var arr &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt;[] { &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"'a'"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"'b'"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"'c'"&lt;/span&gt; };&lt;br /&gt;    var s &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Foo("&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;+&lt;/span&gt; String.Join(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;", "&lt;/span&gt;, arr) &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;+&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;")"&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;// s == "Foo('a', 'b', 'c')"&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;{&lt;br /&gt;    var arr &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt;[] { &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"arg1"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"arg2"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"arg3"&lt;/span&gt; };&lt;br /&gt;    var s &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Foo("&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;+&lt;/span&gt; String.Join(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;", "&lt;/span&gt;, arr) &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;+&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;")"&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;// s == "Foo(arg1, arg2, arg3)"&lt;/span&gt;&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Metoda String.Join spelnia znakomicie swoja role.&lt;/P&gt;
&lt;H5&gt;2. Wygenerowanie tekstu gdzie mamy sekwencje takich samych wartosci, poprzedzielanych jakims inneym tekstem (przecinek, tabulator, nowa linia)&lt;/H5&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;var s &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; String.Join(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"; "&lt;/span&gt;, Enumerable.Repeat(DateTime.Today.ToString(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"yyyy-MM-dd"&lt;/span&gt;), 5).ToArray());&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;// s == "2008-08-22; 2008-08-22; 2008-08-22; 2008-08-22; 2008-08-22"&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Ponownie metoda String.Join, lecz tym razem tablice generujemy pomocnicza konstrukcja Enumerable.Repeat&lt;/P&gt;
&lt;H5&gt;3. Wygenerowanie tekstu gdzie mamy sekwencje wartosci, poprzedzielanych jakims inneym tekstem&lt;/H5&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;var s &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Foo("&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;+&lt;/span&gt; String.Join(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;", "&lt;/span&gt;, Enumerable.Range(1, 4).Select(i =&amp;gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"arg"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;+&lt;/span&gt; i).ToArray()) &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;+&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;")"&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;// s == "Foo(arg1, arg2, arg3, arg4)"&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Ponownie metoda String.Join, lecz tym razem tablice generujemy pomocnicza konstrukcja Enumerable.Range razem z Select.&lt;/P&gt;
&lt;P&gt;W starych czasach (pewnie w&amp;nbsp;okolicach zdobywania Berlina) stosowalem StringBuildera i flagi LUB generowalem tablice za pomoca for i uzywalem String.Join. Oczywiscie nie zawsze takie konstrukcje sie nadaja, zwlaszcza ze w niektorych przypadkach performance (CPU, memory)&amp;nbsp;moze cierpiec. Ale jesli uzywamy tego z umiarem czy w szablonach T4 (stad wzial sie pomysl na ten tekst), to jest wedlug mnie jak najbardziej na miejscu.&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1799" width="1" height="1"&gt;</content><author><name>Wojciech Gebczyk</name><uri>http://zine.net.pl/members/Wojciech+Gebczyk.aspx</uri></author><category term="Text Template" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Text+Template/default.aspx" /><category term="Text" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Text/default.aspx" /><category term="Template" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Template/default.aspx" /><category term="Note" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Note/default.aspx" /><category term="Notatka" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Notatka/default.aspx" /><category term="String" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/String/default.aspx" /></entry><entry><title>[Ww.VS] Szablony tekstowe w VS2008</title><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/archive/2008/07/21/ww-vs-szablony-tekstowe-w-vs2008.aspx" /><id>http://zine.net.pl/blogs/windywinter/archive/2008/07/21/ww-vs-szablony-tekstowe-w-vs2008.aspx</id><published>2008-07-21T19:43:00Z</published><updated>2008-07-21T19:43:00Z</updated><content type="html">&lt;P&gt;Od chwili pojawienia się DSL Tools dla Visual Studio, dostępne były szablony tekstowe&amp;nbsp;T4. Pisał o nich &lt;A href="http://zine.net.pl/blogs/arkadiusz_wasniewski/default.aspx"&gt;Arek&lt;/A&gt; w drugim &lt;A href="http://zine.net.pl/files/folders/zine2006/entry62.aspx"&gt;Zine&lt;/A&gt;. Wraz z Visual Studio 2008, bez instalowania SDK czy DSL Tools, szablony T4&amp;nbsp;są dostepne "z pudełka". Zreszta &lt;A href="http://zine.net.pl/blogs/arkadiusz_wasniewski/archive/2008/07/20/refaktoryzacja-metod-zwrotnych.aspx"&gt;ostatni wpis na blogu&lt;/A&gt; Arka (ten w ktorym używa takich skomplikowanych zwrotów jak refaktoryzacja czy metoda zwrotna kojarząca mi się z kolejami).&lt;/P&gt;
&lt;H4&gt;Jak najszybciej użyć T4?&lt;/H4&gt;
&lt;P&gt;Poprostu należy dodać plik o rozszerzeniu tt do projektu i VS2008 automatycznie podłączy CustomTool "TextTemplatingFileGenerator" i wygeneruje podłączony plik cs.&lt;/P&gt;
&lt;P&gt;Wystarczy teraz w pliku napisać cos takiego:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;namespace&lt;/span&gt; MyApp {&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;class&lt;/span&gt; Class1 {&lt;br /&gt;&amp;lt;# &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;foreach&lt;/span&gt; (&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; name &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;in&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt;[] { &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Aaa"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Bbb"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Ccc"&lt;/span&gt; }) { #&amp;gt;&lt;br /&gt;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; &amp;lt;#&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; name #&amp;gt; { get; set; }&lt;br /&gt;&amp;lt;# } #&amp;gt;&lt;br /&gt;  }&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Aby otrzymać taki wynik:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;namespace&lt;/span&gt; MyApp {&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;class&lt;/span&gt; Class1 {&lt;br /&gt;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; Aaa { get; set; }&lt;br /&gt;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; Bbb { get; set; }&lt;br /&gt;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; Ccc { get; set; }&lt;br /&gt;  }&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;H4&gt;Parę uwag przy dodawaniu szablonów T4&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Za pierwszym razem możemy dostać ostrzerzenie "Security Warning" informujące o niebezpieczeństwie zniszczenia komputera pewnie razem z księżycem. Najlepiej potwierdzić za pomocą OK, zaznaczając wczesniej CheckBox "Do not show this message again". 
&lt;LI&gt;Plik tekstowy bez dyrektyw szablonu (znaczników na początku pliku &amp;lt;#@ i #&amp;gt;) czy znaczników renderowania, również jest poprawnym szablonem, który generuje tekst identyczny z zawartościa szablonu 
&lt;LI&gt;Wygodnie jest dodac nowy szablon za pomocą opcji "Add&amp;gt;New Item...", wybrać dowolny tekstowy plik jak Class czy Code File zmieniając rozszerzenie pliku na ".tt" zamiast ".cs" 
&lt;LI&gt;Standardowo plik generowany pod szablonem ma rozszerzenie ".cs" (to w przypadku projektów C#, zapewne w przypadku projektów VB będzie to ".vb" - nie sprawdzałem). Wiąże się to również z tym że zachowanie pliku w projekcie będzie takie jak typowego pliku o tym rozszerzeniu - w przypadku plików ".cs" "Build Action" będzie ustawiony na "Compile". 
&lt;LI&gt;Jesli wybierzemy inny plik (na przykład XML File), to standardowo dostaniemy wygenerowany plik ".cs". Generowane rozszerzenie można zmienić dodając dyrektywę output na przykład tak: &amp;lt;#@ output extension="xml" #&amp;gt; - koniecznie na początku pliku! 
&lt;LI&gt;Jesli plik szablonu o rozszerzeniu ".tt" skopiowany do schowka (na przykład z pulpitu, czy Exploratora Windows) wkleimy do projektu, to również poprawnie zarejestruje nam sie szablon. 
&lt;LI&gt;Jesli istniejącemu plikowi (na przykład ".cs") zmienimy rozszerzenie na ".tt", to znowu otrzymamy działający plik szablonu. Jedyna niedogodnościa może być to że wygenerowany plik pod szablonem będzie miał w nazwie suffix "1" (lub inna cyfrę). Można tego uniknąć stosując inną metodę, lub ręcznie edytując plik projektu ".csproj" (Unload Project a potem Edit) i usuwając element "LastGenOutput" z elementu odpowiadającego szablonowi. Po ponownym załadowaniu należy usunąć poprzednio wgenerowany plik i wymusić generację ponownie (opcja Run Custom Tool).&lt;/LI&gt;&lt;/OL&gt;
&lt;H4&gt;Mały bonus&lt;/H4&gt;
&lt;P&gt;&lt;A href="http://zine.net.pl/files/folders/1593/download.aspx"&gt;W archiwum ZIP&lt;/A&gt;, znajdują się 4 pliki szablonów. Wystarczy je rozpakować, skopiować i wkleić do projektu, aby otrzymać parę klas "utilsowych".&lt;/P&gt;
&lt;P&gt;Guard i GuardDebug - to klasy podobne do Assert, lecz posiadające API bazujące na xUnit.&lt;/P&gt;
&lt;P&gt;Entries - to zbiór prostych klas-pojemników, do zastosowań wewnątrz implementacyjnych (nie zalecane "wystawianie" tych typów w publicznym API).&lt;/P&gt;
&lt;P&gt;Przykładowe użycie:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;Guard.NotNull(param1, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Param1 cannot be null."&lt;/span&gt;);&lt;br /&gt;GuardDebug.NotNullOrEmpty(name, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Entity name cannot be empty."&lt;/span&gt;);&lt;br /&gt;var e &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; Entry&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;(1, 2, 3);&lt;br /&gt;Guard.InRange(e.Value2, e.Value1, e.Value3, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Entry constraint not satisfied."&lt;/span&gt;);&lt;br /&gt;var map &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt;, Entry&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;();&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Jeśli macie jakieś uwagi zapraszam do komentowania lub kontaktu mailowego.&lt;/P&gt;
&lt;P&gt;Oczywiscie standardowy disclaimer ze nei odpowiadam za problemy, wybuchy etc.&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1591" width="1" height="1"&gt;</content><author><name>Wojciech Gebczyk</name><uri>http://zine.net.pl/members/Wojciech+Gebczyk.aspx</uri></author><category term="Text Template" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Text+Template/default.aspx" /><category term="Text" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Text/default.aspx" /><category term="Template" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Template/default.aspx" /><category term="Szablon" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Szablon/default.aspx" /><category term="Custom" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Custom/default.aspx" /><category term="VS" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/VS/default.aspx" /><category term="VS2008" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/VS2008/default.aspx" /></entry><entry><title>[Ww.Text] CustomConfig2 - czyli jak zrobic aby sie nie narobic</title><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/archive/2008/06/12/ww-text-customconfig2-czyli-jak-zrobic-aby-sie-nie-narobic.aspx" /><id>http://zine.net.pl/blogs/windywinter/archive/2008/06/12/ww-text-customconfig2-czyli-jak-zrobic-aby-sie-nie-narobic.aspx</id><published>2008-06-12T08:56:00Z</published><updated>2008-06-12T08:56:00Z</updated><content type="html">&lt;P&gt;Wczoraj przeczytaLem post &lt;A href="http://zine.net.pl/blogs/dario-g/"&gt;Darka&lt;/A&gt;&amp;nbsp;omawiający hierarchiczne &lt;A href="http://zine.net.pl/blogs/dario-g/archive/2008/06/11/konfiguracja-aplikacji-wlasne-podejscie.aspx"&gt;pliki konfiguracyjne&lt;/A&gt;. Podczas czytania naszły mnie 3 mysli.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Kropkowana notacja przypomina mi Javowe properties (czy to jescze tak sie nazywa?). Mialem z tym doczynnienia daawno temu jak jeszcze cos robilem przy Java. Srednio mi sie to posdobalo i do dzis uwazam ze reprezentacja hierarchii wartosci za pomoca notacji kropkowej a nie skorzystanie z gotowego, znanego, popularnego, sprawdzonego rozwiazania nie jest&amp;nbsp;najszczesliwszym rozwiazaniem (do typowych zastosowan, jako ze na pewno znajda sie zastosowanie gdzie take java-ini-like rozwiazanie sprawdzi sie duzo lepiej niz XML). 
&lt;LI&gt;Po moich ostatnich "zawodowych" walkach z przetwarzaniem plikow tekstowych i problemami stron kodowych, unicode, kompatybilnosci wstecz i wprzod (na szczescie bez kompatybilnosci gora-dol czy prawo-lewo ;-) ) ustawiem regionalnych, jezyka systemu i non-win systemow - cisnienie mi skoczylo&amp;nbsp;na mysl o sledzeniu problemow i ich rozwiazywaniu. Po pierwszym tekscie nie widac na razie jak tego typu problemy moga byc rozwiazane. Prawdopodobnie dlatego ze &lt;A href="http://zine.net.pl/blogs/dario-g/"&gt;Darek&lt;/A&gt; nie wymaga podobnej funkcjonalnosci od tego rozwiazania i jemu to wystarcza to jest calkowicie w porzadku. 
&lt;LI&gt;Pozazdroscilem checi pisania, testowania, dokumentowania, wdrazania tego rozwiazania w zespole, jakoze jestem leniwa osoba. Z tego tez powodu powstal ten blog, poniewaz postanowilem zrobic podobna funkcjonalnosc korzystajac z wbudowanej funkcjonalnosci w .NET Frameworka.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Configuration w .NET Frameworku wspiera chyba od poczatku hierarchiczne pliki konfiguracyjne. Przeciez po instalacji mamy machine.config i "app.config". Ten drugi moze zmienic "odziedziczone" wlasnosci z machine.config lub dodac nowe a nawet usunac - oczywiscie wszystko "lokalnie" w ramach aplikacji. Wiec wykorzystajmy ta infrastrukture do "naszych" celow - czyli rozwiazania ktore posiada glowny plik konfiguracyjny oraz opcjonalne per user nadpisane ustawienia.&lt;/P&gt;
&lt;H3&gt;Nie stadardowy plik konfiguracyjny&lt;/H3&gt;
&lt;P&gt;Najpierw pokaze jak zaladowac konfiguracje z prawie dowolnego pliku. korzystajac z metody ConfigurationManager.OpenExeConfiguration(string exePath) mozemy zaladowac plik konfiguracyjny dla wskazanego pliku "exe" (a tak naprawde dowolnego pliku) gdzie plik konfiguracyjny to exePath z dodanym sufiksem ".config".&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;const&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; cfg &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"&amp;lt;?xml version='1.0' encoding='utf-8' ?&amp;gt;&lt;br /&gt;    &amp;lt;configuration&amp;gt;&lt;br /&gt;      &amp;lt;configSections&amp;gt;&lt;br /&gt;        &amp;lt;section name='mySection' type='ZineNet.CustomCfg2.MySection, ZineNet.CustomCfg2'/&amp;gt;&lt;br /&gt;      &amp;lt;/configSections&amp;gt;&lt;br /&gt;      &amp;lt;mySection&amp;gt;&lt;br /&gt;        &amp;lt;myProperties&amp;gt;&lt;br /&gt;          &amp;lt;add name='p1' value='v1' /&amp;gt;&lt;br /&gt;          &amp;lt;add name='p2' value='v2' /&amp;gt;&lt;br /&gt;          &amp;lt;add name='p4' value='v4' /&amp;gt;&lt;br /&gt;        &amp;lt;/myProperties&amp;gt;&lt;br /&gt;      &amp;lt;/mySection&amp;gt;&lt;br /&gt;    &amp;lt;/configuration&amp;gt;"&lt;/span&gt;;&lt;br /&gt;File.WriteAllText(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"CfgDir\Demo1.tmp"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;""&lt;/span&gt;);&lt;br /&gt;File.WriteAllText(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"CfgDir\Demo1.tmp.config"&lt;/span&gt;, cfg, Encoding.UTF8);&lt;br /&gt;&lt;br /&gt;var exeCfg &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; ConfigurationManager.OpenExeConfiguration(Path.GetFullPath(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"CfgDir\Demo1.tmp"&lt;/span&gt;));&lt;br /&gt;var myCfg &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; (MySection)exeCfg.GetSection(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"mySection"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;foreach&lt;/span&gt; (MyPropertyElement p &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;in&lt;/span&gt; myCfg.MyProperties) {&lt;br /&gt;    Console.WriteLine(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"{0}:{1}"&lt;/span&gt;, p.Name, p.Value);&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;W tym przykladzie tworze plik na dysku, gdze zapisuje przykladowa konfiguracje. Nastepnie otwieram plik konfiguracyjny wskazujac na tymczasowy/sztuczny plik CfgDir\Demo1.tmp. Metoda OpenExeConfiguration sprawdza istnienie pliku przekazanego w argumencie exePath, pomimo iz z niech nie korzysta. Dlatego wytwarzam rowniez pusty plik o takiej nazwie.&lt;/P&gt;
&lt;H3&gt;Dowolne hierarchiczne pliki konfiguracyjne&lt;/H3&gt;
&lt;P&gt;Teraz przyklad blizszy temu co zaprezentowal &lt;A href="http://zine.net.pl/blogs/dario-g/"&gt;Darek&lt;/A&gt; w swoim tekscie. Utworze 2 pliki konfiguracyjne, zaladuje oba uzyskujac ten sam typ sekcji konfiguracyjnej jak w przykladzie pierwszym.&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;const&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; cfg &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"&amp;lt;?xml version='1.0' encoding='utf-8' ?&amp;gt;&lt;br /&gt;    &amp;lt;configuration&amp;gt;&lt;br /&gt;      &amp;lt;configSections&amp;gt;&lt;br /&gt;        &amp;lt;section name='mySection' type='ZineNet.CustomCfg2.MySection, ZineNet.CustomCfg2' allowExeDefinition='MachineToRoamingUser'/&amp;gt;&lt;br /&gt;      &amp;lt;/configSections&amp;gt;&lt;br /&gt;      &amp;lt;mySection&amp;gt;&lt;br /&gt;        &amp;lt;myProperties&amp;gt;&lt;br /&gt;          &amp;lt;add name='p1' value='v1' /&amp;gt;&lt;br /&gt;          &amp;lt;add name='p2' value='v2' /&amp;gt;&lt;br /&gt;          &amp;lt;add name='p4' value='v4' /&amp;gt;&lt;br /&gt;        &amp;lt;/myProperties&amp;gt;&lt;br /&gt;      &amp;lt;/mySection&amp;gt;&lt;br /&gt;    &amp;lt;/configuration&amp;gt;"&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;const&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; cfgLocal &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"&amp;lt;?xml version='1.0' encoding='utf-8' ?&amp;gt;&lt;br /&gt;    &amp;lt;configuration&amp;gt;&lt;br /&gt;      &amp;lt;mySection&amp;gt;&lt;br /&gt;        &amp;lt;myProperties&amp;gt;&lt;br /&gt;          &amp;lt;remove name='p2' /&amp;gt;&lt;br /&gt;          &amp;lt;add name='p5' value='v5' /&amp;gt;&lt;br /&gt;        &amp;lt;/myProperties&amp;gt;&lt;br /&gt;      &amp;lt;/mySection&amp;gt;&lt;br /&gt;    &amp;lt;/configuration&amp;gt;"&lt;/span&gt;;&lt;br /&gt;File.WriteAllText(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"CfgDir\Demo2.config"&lt;/span&gt;, cfg, Encoding.UTF8);&lt;br /&gt;File.WriteAllText(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"CfgDir\Demo2.Local.config"&lt;/span&gt;, cfgLocal, Encoding.UTF8);&lt;br /&gt;&lt;br /&gt;var exeCfg &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; ConfigurationManager.OpenMappedExeConfiguration(&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; ExeConfigurationFileMap {&lt;br /&gt;        ExeConfigFilename &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; Path.GetFullPath(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"CfgDir\Demo2.config"&lt;/span&gt;),&lt;br /&gt;        RoamingUserConfigFilename &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; Path.GetFullPath(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"CfgDir\Demo2.Local.config"&lt;/span&gt;)&lt;br /&gt;    }, &lt;br /&gt;    ConfigurationUserLevel.PerUserRoaming&lt;br /&gt;);&lt;br /&gt;var myCfg &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; (MySection)exeCfg.GetSection(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"mySection"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;foreach&lt;/span&gt; (MyPropertyElement p &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;in&lt;/span&gt; myCfg.MyProperties) {&lt;br /&gt;    Console.WriteLine(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"{0}:{1}"&lt;/span&gt;, p.Name, p.Value);&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Tym razem uzywam innej metody OpenMappedExeConfiguration gdzie przekazuje obkekt ExeConfigurationFileMap. Obiekt file map zawiera sciezki do konkretnych plikow konfiguracyjnych a nie zaleznych plikow "exe". Za pomoca drugiego argumentu ConfigurationUserLevel specyfikujemy ktore pliki musza byc zaladowane, a ktore zignorowane, jako ze w typie ExeConfigurationFileMap mozeny wyspecyfikowac 4 pliki konfiguracyjne roznego poziomu. Musimy zezwolic na ta operacje przy definicji sekcji w "pierwszym" pliku konfiguracyjnym za pomoca&amp;nbsp;atrybutu "allowExeDefinition".&lt;/P&gt;
&lt;H3&gt;Jeszcze wiecej funkcjonalnosci we wlasnych plikach&lt;/H3&gt;
&lt;P&gt;Powyzszy przyklad dostarcza z grubsza funkcjonalnosci zaprezentowanej przez Darka. Lecz mozemy skorzystac bez zmiany kodu przetwarzajacego, z pozostalej funkcjonalnosci. Dla przykladu pokaze mozliwosc blokowania redefiniowania fragmentow konfiguracji.&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;const&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; cfg &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"&amp;lt;?xml version='1.0' encoding='utf-8' ?&amp;gt;&lt;br /&gt;    &amp;lt;configuration&amp;gt;&lt;br /&gt;      &amp;lt;configSections&amp;gt;&lt;br /&gt;        &amp;lt;section name='mySection' type='ZineNet.CustomCfg2.MySection, ZineNet.CustomCfg2' allowExeDefinition='MachineToRoamingUser'/&amp;gt;&lt;br /&gt;      &amp;lt;/configSections&amp;gt;&lt;br /&gt;      &amp;lt;mySection&amp;gt;&lt;br /&gt;        &amp;lt;myProperties&amp;gt;&lt;br /&gt;          &amp;lt;add name='p1' value='v1' /&amp;gt;&lt;br /&gt;          &amp;lt;add name='p2' value='v2' lockItem='true' /&amp;gt;&lt;br /&gt;          &amp;lt;add name='p4' value='v4' /&amp;gt;&lt;br /&gt;        &amp;lt;/myProperties&amp;gt;&lt;br /&gt;      &amp;lt;/mySection&amp;gt;&lt;br /&gt;    &amp;lt;/configuration&amp;gt;"&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;const&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; cfgLocal &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"&amp;lt;?xml version='1.0' encoding='utf-8' ?&amp;gt;&lt;br /&gt;    &amp;lt;configuration&amp;gt;&lt;br /&gt;      &amp;lt;mySection&amp;gt;&lt;br /&gt;        &amp;lt;myProperties&amp;gt;&lt;br /&gt;          &amp;lt;remove name='p2' /&amp;gt;&lt;br /&gt;        &amp;lt;/myProperties&amp;gt;&lt;br /&gt;      &amp;lt;/mySection&amp;gt;&lt;br /&gt;    &amp;lt;/configuration&amp;gt;"&lt;/span&gt;;&lt;br /&gt;File.WriteAllText(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"CfgDir\Demo3.config"&lt;/span&gt;, cfg, Encoding.UTF8);&lt;br /&gt;File.WriteAllText(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"CfgDir\Demo3.Local.config"&lt;/span&gt;, cfgLocal, Encoding.UTF8);&lt;br /&gt;&lt;br /&gt;var exeCfg &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; ConfigurationManager.OpenMappedExeConfiguration(&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; ExeConfigurationFileMap {&lt;br /&gt;        ExeConfigFilename &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; Path.GetFullPath(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"CfgDir\Demo3.config"&lt;/span&gt;),&lt;br /&gt;        RoamingUserConfigFilename &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; Path.GetFullPath(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"CfgDir\Demo3.Local.config"&lt;/span&gt;)&lt;br /&gt;    }, &lt;br /&gt;    ConfigurationUserLevel.PerUserRoaming&lt;br /&gt;);&lt;br /&gt;var myCfg &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; (MySection)exeCfg.GetSection(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"mySection"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;foreach&lt;/span&gt; (MyPropertyElement p &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;in&lt;/span&gt; myCfg.MyProperties) {&lt;br /&gt;    Console.WriteLine(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"{0}:{1}"&lt;/span&gt;, p.Name, p.Value);&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Ustawiajac atrybut lockItem='true' na jednej z wlasnych wlasciwosci, nie pozwalamy na redefiniowanie&amp;nbsp;go w "potomnym" pliku konfiguracyjnym. Podczas uruchamiania przykladu trzeciego dostaniemy wyjatek o podobnej tresci: "The attribute 'p2' has been locked in a higher level configuration. (K:\ZineNet\ZineNet.CustomCfg2\bin\Debug\CfgDir\Demo3.Local.config line 5)".&lt;/P&gt;
&lt;H3&gt;Inne uwagi&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;Zamiast hierarchii zagniezdzania elementow, mozna ja "rozplaszczyc" i zastosowac notacje kropkowa podobnie jak to uczynil &lt;A href="http://zine.net.pl/blogs/dario-g/"&gt;Darek&lt;/A&gt;. Poprostu trzeba nadpisac w definicji sekcji sposob deserializacji/serializacji 
&lt;LI&gt;Podejscie z zagniezdzaniem elementow XML zamiast notacji kropkowej wymusza na nas stworzenie odpowiednich klas konfiguracji. Zyskujemy na tym walidacje pliku konfiguracyjnegom lecz tracimy na tym ze mamy dodatkowa prace rzemieslnicza zwiazana z ich napisaniem.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=1179" width="1" height="1"&gt;</content><author><name>Wojciech Gebczyk</name><uri>http://zine.net.pl/members/Wojciech+Gebczyk.aspx</uri></author><category term="Text" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Text/default.aspx" /><category term="Article" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Article/default.aspx" /><category term="Artykul" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Artykul/default.aspx" /><category term="Congif" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Congif/default.aspx" /><category term="Konfiguracja" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Konfiguracja/default.aspx" /><category term="Custom" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Custom/default.aspx" /></entry><entry><title>[WG.net] Wzorzec Model View Controller (MVC)</title><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/archive/2008/02/16/wg-net-wzorzec-model-view-controller-mvc.aspx" /><id>http://zine.net.pl/blogs/windywinter/archive/2008/02/16/wg-net-wzorzec-model-view-controller-mvc.aspx</id><published>2008-02-16T14:29:00Z</published><updated>2008-02-16T14:29:00Z</updated><content type="html">&lt;P&gt;Prezentacja z XX spotkania grupy WG.net (XI PGU SqlSever)&amp;nbsp;omawiająca wzorzec MVC.&lt;/P&gt;
&lt;H3&gt;Scenariusz problemu - Edycja danych&lt;/H3&gt;
&lt;P&gt;Jednym z najczęstszych przypadków tworzenia aplikacji jest umożliwienie użytkownikowi interakcji z danymi - formatkowy edytor danych. Zakres wymaganej funkcjonalności obejmuje bardzo często następujące wymagania:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Zapytanie do bazy - wszystkie / tylko wybrane 
&lt;LI&gt;Przepisanie danych do kontrolek - problemy z DBNull, null, etc 
&lt;LI&gt;Obsługa słowników 
&lt;LI&gt;Obsługa akcji Edit/Add/Remove/BrowseDictionary 
&lt;LI&gt;Sprawdzenie poprawności 
&lt;LI&gt;INSERT/UPDATE/DELETE do bazy&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Implementacja całości wymagań w jednym pliku asp/php/form etc powoduje nieczytelność kodu. Przeglądanie, a co ważniejsze koszt utrzymywania kodu rośnie coraz szybciej wraz ze wzrostem dodatkowej funkcjonalności.&lt;/P&gt;
&lt;H3&gt;Rozwiązanie - wzorzec MVC&lt;/H3&gt;
&lt;P&gt;Rozwiązaniem problemu jest zastosowanie wzorca Model View Controller (MVC). Polega to na podzieleniu wymaganej funkcjonalności/odpowiedzialności na 3 komponenty:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Model – przetwarzane dane 
&lt;LI&gt;View – prezentacja danych 
&lt;LI&gt;Controller – sterowanie przepływem danych – logika aplikacji&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Dokładny podział odpowiedzialności jest zależny od konkretnego wariantu wzorca czy implementacji. Dla przykładu rozważmy odpowiedzialność "sprawdzenie poprawności danych". Można włączyć ją do modelu gdy nie jest ona trywialna, a powiązana ściśle z modelem. Walidację można włączyć do widoku, gdzie poszczególne kontrolki mogą ją wykonywać. W przypadku skomplikowanego sprawdzania odpowiedzialność może przejąć kontroler.&lt;/P&gt;
&lt;H3&gt;Warianty&lt;/H3&gt;
&lt;P&gt;Wzorzec MVC posiada wiele wariantów, dostosowywanych do konkretnych technologii, metodyk programowania czy właściwości języka. Zanim zacznie się tworzenie własnej implementacji, warto przejrzeć najpopularniejsze Frameworki MVC przeznaczone dla swojej platformy programistycznej. Zazwyczaj takie gotowce zawierają dodatkową funkcjonalność jak pojemniki IoC, definiowanie przepływem logiki aplikacji, ułatwienia typowych operacji programisty, etc.&lt;/P&gt;
&lt;P&gt;&lt;a href="http://zine.net.pl/files/folders/pliki_do_tekstow/entry802.aspx"&gt;[Prezentacja 20080214_XX_WG_WzorzecMVC.zip]&lt;/a&gt; oraz &lt;a href="http://zine.net.pl/files/folders/pliki_do_tekstow/entry801.aspx"&gt;[Ww.WgNet.MvcCalc.zip]&lt;/a&gt;&lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=799" width="1" height="1"&gt;</content><author><name>Wojciech Gebczyk</name><uri>http://zine.net.pl/members/Wojciech+Gebczyk.aspx</uri></author><category term="Wzorzec" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Wzorzec/default.aspx" /><category term="MVC" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/MVC/default.aspx" /><category term="Pattern" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/Pattern/default.aspx" /><category term="WG.net" scheme="http://zine.net.pl/blogs/windywinter/archive/tags/WG.net/default.aspx" /></entry><entry><title>[Ww.Web] SilverLight, SilverDark, Konkrety</title><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/archive/2008/01/24/ww-web-silverlight-silverdark-konkrety.aspx" /><id>http://zine.net.pl/blogs/windywinter/archive/2008/01/24/ww-web-silverlight-silverdark-konkrety.aspx</id><published>2008-01-24T13:30:00Z</published><updated>2008-01-24T13:30:00Z</updated><content type="html">&lt;P&gt;Poniżej parę konkretnych uwag do SilverLighta (SL), aby poprzednie narzekanie na SL nie było gołosłowne. Nie są to wszystkie moje uwago do SL, ale wydaje mi się wystarczająca ilość aby uzasadnić mój punkt widzenia z poprzedniego postu.&lt;/P&gt;
&lt;P&gt;1. Środowiska programisty/projektanta/tego-co-robi-SL-aplikację &lt;/P&gt;
&lt;P&gt;Spróbowałem pracować z Blendem oraz VS 2008. Niestety, kontrolki z Toolkita nie pokazują się w designerze i w dodatku z jakiegoś magicznego powodu po uruchomieniu wyglądają dziwnie (niektóre elementy są powyciągane, a niektóre mają dobre rozmiary). Zrezygnowałem z Blenda i zacząłem używać VS2008. Ręczna praca z XAMLem oraz kodem "pode spodem" przyniosła efekty - na statycznych plikach z tekstem do wyświetlenia działało dobrze! Niestety próba udynamicznienia aplikacji spowodowała stratę około 2 godzin (jeden wieczór zmarnowany), ponieważ w wersji 1.1 Downloader uruchomiony lokalnie (nie przez serwer Web) nie pozwala "ściągnąć" plików leżących po sąsiedzku ze strona HTML aplikacji SL. Błąd wyświetlany jest baaardzo ogólny i nie wiadomo czy przypadkiem to początkujący SLowiec nie popełnił błędu. Informację o tym znalazłem na forum dyskusyjnym. &lt;/P&gt;
&lt;P&gt;2. Debugowanie aplikacji &lt;/P&gt;
&lt;P&gt;Chciałem mieć 3 projekty: w pierwszym logika konwersji, w drugim kontrolki związane z SL, a w trzecim prosta aplikacja w ASP.NET zajmująca się publikowaniem Package pod wirtualnymi adresami URL. Tak naprawdę projekt SL i ASP.NET powinny być razem, jako że występują w tym samym Web Site. Niestety nie udało mi się dodać projektu z kontrolkami Toolkita do aplikacji ASP.NET. Wyjściem okazało się dołączenie projektu Toolkita do projektu SL, ręczne włożenie projektu SL do katalogu z projektem ASP.NET i zmiany w pliku solution. Aby debugować jednocześnie ASP.NET i SL należy ustawić oba projekty jako startowe. Dostajemy przy starcie 2 przeglądarki - jedna od ASP.NET (localhost), a druga do SL (local file system) i musimy ręcznie przeklejać i koordynować obie przeglądarki. &lt;/P&gt;
&lt;P&gt;3. Uboga podstawowa funkcjonalność &lt;/P&gt;
&lt;P&gt;Jak pisałem w poprzednim poście, są tylko naprawdę podstawowe kontrolki. API SL pod .NET jest bardzo zubożone - brak przeładowań metod dla typowych operacji, wygląda jak jakiś wrapper na coś z zupełnie innej bajki. Taka klasa Downloader - koszmarne API, wszystko "lata" jako tekst. XamlReader - tylko metoda Load z parametrem string reprezentującym tekst do sparsowania - nie można przekazać strumienia danych. XamlReader zachowuje się dodatkowo nie przewidywalnie - ten sam tekst przekazany do metody Load czasami przetwarza się poprawnie a czasami zgłasza błąd (Wygląda jak by po przetworzeniu określonej ilości znaków? elementów? zgłaszał błąd - problem z wewnętrznym buforem?). &lt;/P&gt;
&lt;P&gt;4. Brak kontrolki TextBox &lt;/P&gt;
&lt;P&gt;To tak ważna kontrolka, że brak jej jest jakimś nieporozumieniem lub pomyłką. Resztę na ten temat pominę milczeniem. &lt;/P&gt;
&lt;P&gt;5. Brak funkcjonalności layoutowania kontrolek &lt;/P&gt;
&lt;P&gt;Pozycjonowanie absolutne, a layoutowanie ręczne w kodzie. W przypadku zegarka to może i zda egzamin jak ma się kilka elementów bez interakcji użytkownika. Ale zastanówcie się ile trzeba spędzić czasu aby zrobic Grida ze stylami, szablonami? Dyskwalifikacja produktu. &lt;/P&gt;
&lt;P&gt;6. Brak bindowania danych &lt;/P&gt;
&lt;P&gt;Ręczne "wpisywanie danych" w kontrolkę (TextBlock/Glyphs). Takie "tricki" można było robić już w HTMLu i PHP/ASP. Po co do tego wracać? Dyskwalifikacja produktu. &lt;/P&gt;
&lt;P&gt;7. Możliwości SL, a WPF &lt;/P&gt;
&lt;P&gt;Gdzieś wyczytałem (jak zwykle nie pamiętam gdzie), że SL daje programiście duże możliwości, ponieważ jeśli ktoś chce to może zaimplementować na nim funkcjonalność WPF, a z tego wniosek, że to jest technologia porównywalna z WPF. Zgodzę się że technicznie jest możliwe przenieść sporą część funkcjonalności (nie napisze całość jako że nie znam tak dokładnie WPF), ale jakim kosztem czasowym? &lt;/P&gt;
&lt;P&gt;Czasy gdy kilka lat temu walczyło się z materią, pisząc w HTML/JavaScript elementy z "dużych, okienkowych aplikacji" dla mnie przynajmniej już minęły. Nie cieszy mnie już sama możliwość zrobienia Czegoś bez względu na koszt czasowy. Odnosząc to do praktycznego zastosowania, jak widzę sposoby pracy i efekty SL: &lt;/P&gt;
&lt;P&gt;a. SL jest przeznaczony dla aplikacji bazujących na HTML i przeglądarce. Aktualnie jest sens użycia tego jeśli klient zażyczył sobie JAWNIE aplikacji "webowej" z wodotryskami. Tak naprawdę jeśli klient chce intranetową, "bogatą" (bogatą w sensie UX/UI) aplikację są inne technologie zapewniające to, bez potrzeby debugowania JavaScript i udawania ze HTML jest prawie jak aplikacja okienkowa. Nie będę rozpisywał się o tym "prawie". &lt;/P&gt;
&lt;P&gt;b. Jeśli już trzeba użyć HTML, to wtedy SL można użyć do prostych rzeczy, jak "flashowe" menu, ładne wykresy z odrobiną interakcji. &lt;/P&gt;
&lt;P&gt;c. SL używamy do rzeczy prostych, ponieważ napisanie złożonej aplikacji (nawet formatowy edytor danych) wymaga naprawdę duuużo roboczo-godzin lub zasobów pieniężnych (na jedno wychodzi) . A to ze względu na potrzebę napisania tych kontrolek od początku, bądź kupna od jakiejś firmy. Z pobieżnego przeglądu dostępnych kontrolek jeszcze im daleko z funkcjonalnością choćby do podstawowych kontrolek WPFa. &lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=760" width="1" height="1"&gt;</content><author><name>Wojciech Gebczyk</name><uri>http://zine.net.pl/members/Wojciech+Gebczyk.aspx</uri></author></entry><entry><title>[Ww.Web] SilverDark</title><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/archive/2008/01/24/ww-web-silverdark.aspx" /><id>http://zine.net.pl/blogs/windywinter/archive/2008/01/24/ww-web-silverdark.aspx</id><published>2008-01-24T12:29:00Z</published><updated>2008-01-24T12:29:00Z</updated><content type="html">&lt;P&gt;Postanowiłem wziąć udział w konkursie Silverlighta (SL). Długo szukałem tematu. Po akademicku zacząłem w ostatniej chwili (czytaj: 2 dni temu). Poległem.&lt;/P&gt;
&lt;H5&gt;Czas pre-SL &lt;/H5&gt;
&lt;P&gt;WPFem zainteresowałem się gdzieś w początkach jego powstawania. Czekałem z zapoznaniem się z WPF tak naprawdę do czasu którejś z wersji Beta. Ciężka to była nauka, porównywalna chyba do nauki Flash 4. Do chwili obecnej napisałem 2-3 aplikacje, które są większe niż HelloWorld. Zderzyłem się z paroma problemami, zmieniłem sposób myślenia/oczekiwania co do pewnych komponentów WPF. Aktualnie uznaję WPF za dobrą alternatywę dla WinForms - może nie dla każdego zastosowania, lecz dla zdecydowanej ich większości. Potem pojawiły się informacje o WPF/E. Z nazwy oczekiwałem, iż będzie to taki WPF, ale na inne platformy. &lt;/P&gt;
&lt;H5&gt;"Lights, Camera, Action!"&lt;/H5&gt;
&lt;P&gt;Z oglądania kodu SL na blogach i w przykładach, wszystko wygląda fajnie, prosto i ładnie. Przykładowe aplikacje pokazują co można z tym zrobić. Myślałem, że zbieżność WPFa i SL będzie duża (w końcu pierwsza nazwa to WPF/E), i że za pomocą części wspólnej można tworzyć aplikacje WPF dobrze przenaszalne do SL. Och! Jaki ja bylem naiwny. &lt;/P&gt;
&lt;H5&gt;"Shileds up, weapons online" &lt;/H5&gt;
&lt;P&gt;Pojawia sie konkurs SL. Jest powód aby zapoznać się technologią. Najpierw wybór jaką aplikacje napiszę. Powstało wiele pomysłów: przeglądarka dokumentów (konwersja z DOCX,HTML,CHM,ect -&amp;gt;FlowDocument-&amp;gt;XPS), dashboard z kilkoma elementami, smart tagi do HTMLa, itp. Zdecydowanym się w końcu na pierwszy pomysł - XPS reader. Pierwsze testy wykazały ze wystarczy z FixedPage wyrzucić kilka atrybutów i elementów i pozostanie część kompatybilna z XAMLem SL (okazało się że podobne podejście zastosował niejaki &lt;A href="http://blogs.msdn.com/delay/archive/2007/05/22/lighting-up-the-xml-paper-specification-proof-of-concept-xps-reader-for-silverlight.aspx"&gt;Delay&lt;/A&gt;). Potem zaczęły się kłopoty... Na przykład: jednym z ostatnich problemów jest niepoprawne parsowanie tekstu XAML. To znaczy ten sam tekst raz jest dobrze parsowany, a następnym razem zgłaszany jest wyjątek XamlParseException - co do znaku, co do bajtu ten sam tekst raz jest przetwarzany a raz nie. &lt;/P&gt;
&lt;H5&gt;Nastały mroczne czasy&lt;/H5&gt;
&lt;P&gt;Z końcu zrezygnowałem z udziału w konkursie. Na samą myśl o SL w tej chwili przychodzą mi na myśl w większości niecenzuralne określenia. Gdzieś, ktoś, kiedyś napisał ze SL to jeden ze sposobów na tworzenie aplikacji RIA - niestety według mnie w obecnym stanie wytworzenie nie trywialnej aplikacji wymaga samozaparcia i dużej ilości czasu. &lt;/P&gt;
&lt;H5&gt;Troche marudzenia &lt;/H5&gt;
&lt;P&gt;Dla osób które "programowały w HTMLu" budując za pomocą HTML/JavaScript niestandardowe elementy UI, spojrzenie na SL może wydawać się ożywczym zbawieniem! Większa szybkość, możliwości czy ujednolicenie API (żadnych CrossBrowser trików!) przyciąga. Ale na tym poziomie podobną funkcjonalność oferuje Flash (chyba? Niestety przestałem interesować się tą technologią gdzieś w okolicach wersji 6 lub 7). Zaletą SL wobec Flash jest prawdopodobnie brak naleciałości z poprzednich wersji jako ze jest to pierwsza wersja. &lt;/P&gt;
&lt;P&gt;Z drugiej strony dla osoby która poznała najpierw WPF, a teraz próbuje użyć SL to coś z pogranicza koszmaru i komedii. Koszmarem jest samo programowanie, szukanie dokumentacji, debugowanie aplikacji i dochodzenie, czy problem leży po stronie programisty czy błędu w SL. Komedią jest literka R ze skrótu (RIA) - w wersji "z pudełka" mamy dostęp do 5 głównych kontrolek/elementów: Canvas, Image, TextBlock, Glyphs i Shape (wraz z pochodnymi). W Toolkicie są dodatkowe kontrolki, które niestety się "rozjeżdżają", mają nieintuicyjne API, ale przynajmniej są. Zgadam się, że do zrobienia sprawnie "aplikacji" zegarek, odtwarzacz filmików bądź "flashowe menu" w zupełności wystarczy. Aby zrobić cos bardziej użytecznego/zaawansowanego, trzeba włożyć w to dużo pracy. &lt;/P&gt;
&lt;P&gt;Po tym pierwszym spotkaniu SL odkładam na półkę z rzeczami nie używanymi. Zresztą sam MS widzi potrzebę re ewaluacji tego produktu jako że 1.1 jest zawieszony i będzie kontynuowany jako 2.0 z poszerzonym zakresem funkcjonalności. Może wrócę do tego produktu, ale nie wcześniej niż udokumentowana, późna wersja Beta. &lt;/P&gt;&lt;img src="http://zine.net.pl/aggbug.aspx?PostID=758" width="1" height="1"&gt;</content><author><name>Wojciech Gebczyk</name><uri>http://zine.net.pl/members/Wojciech+Gebczyk.aspx</uri></author></entry><entry><title>Konkurs Enterprise Library – Policy Injection (PIAB) - Updated</title><link rel="alternate" type="text/html" href="http://zine.net.pl/blogs/windywinter/archive/2007/10/15/konkurs-enterprise-library-policy-injection-piab.aspx" /><id>http://zine.net.pl/blogs/windywinter/archive/2007/10/15/konkurs-enterprise-library-policy-injection-piab.aspx</id><published>2007-10-15T14:40:00Z</published><updated>2007-10-15T14:40:00Z</updated><content type="html">&lt;P&gt;Oto ostatnia odsłona konkursu. Tym razem wprowadzenie do wykorzystania &lt;STRONG&gt;PIAB &lt;/STRONG&gt;przy scalaniu poszczególnych rozwiązań opartych na &lt;A href="http://zine.net.pl/blogs/arkadiusz_wasniewski/archive/2007/09/24/konkurs-enterprise-library-logging-lab.aspx"&gt;LAB&lt;A&gt;, &lt;A href="http://zine.net.pl/blogs/nuwanda/archive/2007/10/01/konkurs-enreprise-library-exception-handling-ehab.aspx"&gt;EHAB&lt;/A&gt; i &lt;A href="http://zine.net.pl/blogs/mgrzeg/archive/2007/10/08/EntLibContestVAB.aspx"&gt;VAB&lt;/A&gt;.&lt;/P&gt;
&lt;H2&gt;Refaktoryzacja do Policy Injection Application Block (PIAB)&lt;/H2&gt;
&lt;P&gt;Jeżeli podczas projektowania aplikacji zdecydowaliśmy się na zastosowanie pewnych wytycznych czy standardów implementacji, wówczas spora część kodu wynikająca z tych ustaleń jest powtarzalna. Niestety, jeśli piszemy coś ręcznie istnieje możliwość popełnienia błędu. Aby uchronić się przed pomyłkami można napisać rozszerzenia lub makra &lt;STRONG&gt;Visual Studio&lt;/STRONG&gt; pomagające nam we wdrażaniu standardów, niestety to zadanie nie należy do najłatwiejszych. Innym sposobem jest użycie narzędzia pozwalającego na zastosowanie elementów programowania aspektowego. Takimi aspektami mogą być na przykład logowanie, obsługa błędów czy walidacja. &lt;STRONG&gt;PIAB&lt;/STRONG&gt; pozwala na dodawanie aspektów do nowych lub istniejących obiektów, dzięki wytwarzaniu obiektów proxy realizujących wymaganą funkcjonalność.&lt;/P&gt;
&lt;H3&gt;Przypadek&lt;/H3&gt;
&lt;P&gt;Walidacja, obsługa wyjątków oraz logowanie używają &lt;STRONG&gt;Application Block&lt;/STRONG&gt;, lecz brak spójnych reguł ich użycia.&lt;/P&gt;
&lt;H3&gt;Rozwiązanie&lt;/H3&gt;
&lt;P&gt;Zlokalizuj fragmenty kodu z walidacją, logowaniem i obsługą wyjątków. Podziel poszczególne przypadki użycia, według sposobu przetwarzania i utwórz reguły ich dotyczące. Zaaplikuj reguły do istniejącego kodu.&lt;/P&gt;
&lt;H3&gt;Uzasadnienie&lt;/H3&gt;
&lt;P&gt;Co nam daje &lt;STRONG&gt;PIAB&lt;/STRONG&gt;? Upraszcza kod aplikacji po przez automatyzowanie pewnych operacji w kodzie oraz zmniejsza ryzyko popełnienia błędu w przypadku ręcznego pisania kodu operacji.&lt;/P&gt;
&lt;P&gt;Załóżmy, że celem logowania jest obsługa pewnych kroków scenariusza działania aplikacji – dla przykładu reguła mówi &lt;STRONG&gt;loguj każde wywołanie operacji obiektów warstwy usług&lt;/STRONG&gt; lub &lt;STRONG&gt;każda zmiana wartości modelu danych powinna być logowana dla celów informacyjnych&lt;/STRONG&gt;. Implementacja powyższych reguł może wyglądać tak, że dodawane są instrukcje logujące na początku i końcu działania metody. Ręczne wytwarzanie takiego kodu jest narażone na błędy oraz trudności związane ze zmianą reguł. W takim przypadku warto jest użyć jakiegoś &lt;STRONG&gt;automatu &lt;/STRONG&gt;który wykona wymagane instrukcje, takim narzędziem jest &lt;STRONG&gt;PIAB&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Podobnie można postąpić w przypadku gdy obsługa wyjątków ma na celu realizację reguł typu: &lt;STRONG&gt;osłoń wyjątek bazy danych po przez zastąpienie go innym na poziomie warstwy usług&lt;/STRONG&gt; lub &lt;STRONG&gt;ukryj każdy wyjątek na poziomie GUI, jednocześnie logując informacje o nim&lt;/STRONG&gt;. Po zdefiniowaniu zasad obsługi reguł i wykorzystaniu istniejącej konfiguracji &lt;STRONG&gt;Application Block&lt;/STRONG&gt;, &lt;STRONG&gt;PIAB&lt;/STRONG&gt; automatycznie wykonywał będzie wskazane reguły.&lt;/P&gt;
&lt;P&gt;W przypadku walidacji również można uprościć kod aplikacji gdy posiadamy spójny zestaw reguł walidowania. &lt;STRONG&gt;PIAB&lt;/STRONG&gt; wspomoże również obsługę reguł postaci &lt;STRONG&gt;Każdy parametr metod warstwy usług musi być poprawny&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Warto dodać iż &lt;STRONG&gt;PIAB&lt;/STRONG&gt; wykorzystuje istniejącą konfigurację &lt;STRONG&gt;VAB&lt;/STRONG&gt;, &lt;STRONG&gt;EHAB&lt;/STRONG&gt; i &lt;STRONG&gt;LAB&lt;/STRONG&gt; dodając tylko same zasady ich aplikowania.&lt;/P&gt;
&lt;H3&gt;Sposób wykonania&lt;/H3&gt;
&lt;P&gt;Mając aplikację używającą poszczególnych &lt;STRONG&gt;Application Block&lt;/STRONG&gt;, pierwszym krokiem jest zastanowienie się nad &lt;STRONG&gt;regułami&lt;/STRONG&gt; jakie chcemy zaimplementować – sposobami jak automatyzować operacje w aplikacji. Kolejnym krokiem jest ustalenie sposobu określenia &lt;STRONG&gt;wytycznych&lt;/STRONG&gt; w konfiguracji &lt;STRONG&gt;PIAB&lt;/STRONG&gt;. Na końcu usuwamy istniejący kod poszczególnych &lt;STRONG&gt;Application Block&lt;/STRONG&gt; i zmieniamy sposób tworzenia obiektów podlegających modyfikacjom.&lt;/P&gt;
&lt;P&gt;Podsumowując mamy następujące kroki:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Określenie &lt;STRONG&gt;reguł,&lt;/STRONG&gt; 
&lt;LI&gt;Konfiguracja PIAB – konfiguracja &lt;STRONG&gt;wytycznych,&lt;/STRONG&gt; 
&lt;LI&gt;Usunięcie istniejącego kodu &lt;STRONG&gt;VAB&lt;/STRONG&gt;, &lt;STRONG&gt;EHAB&lt;/STRONG&gt; i &lt;STRONG&gt;LAB&lt;/STRONG&gt;, 
&lt;LI&gt;Zmiana sposobu tworzenia obiektów.&lt;/LI&gt;&lt;/OL&gt;
&lt;H2&gt;Przykład&lt;/H2&gt;
&lt;P&gt;Cały proces aplikowania &lt;STRONG&gt;PIAB&lt;/STRONG&gt; zaprezentowany zostanie przy użyciu przykładowej aplikacji. &lt;STRONG&gt;Projekt ZineNet.PiabContest.Base&lt;/STRONG&gt; to aplikacja 3 warstwowa używająca &lt;STRONG&gt;VAB&lt;/STRONG&gt;, &lt;STRONG&gt;EHAB&lt;/STRONG&gt; i &lt;STRONG&gt;LAB&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Kontrakt kodu usług bazuje na interfejsach – to znaczy funkcjonalność API usług jest definiowana za pomocą interfejsów. Tworzeniem instancji usług zajmuje się klasa &lt;STRONG&gt;ServiceFactory&lt;/STRONG&gt;.&lt;/P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;namespace&lt;/span&gt; ZineNet.PiabContest.Services {&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;interface&lt;/span&gt; IFooService {&lt;br /&gt;    FooEntity GetById(Guid id);&lt;br /&gt;    List&amp;lt;FooEntity&amp;gt; GetByNameStart(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; namePart);&lt;br /&gt;    FooEntity Set(FooEntity value);&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;void&lt;/span&gt; Remove(Guid id);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;namespace&lt;/span&gt; ZineNet.PiabContest.Model {&lt;br /&gt;  [HasSelfValidation]&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sealed&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;class&lt;/span&gt; FooEntity {&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; FooEntity() { _id &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; Guid.NewGuid(); }&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; FooEntity(Guid id, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; name, DateTime from, DateTime to) {&lt;br /&gt;      Id &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; id;&lt;br /&gt;      Name &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; name;&lt;br /&gt;      ValidFrom &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; from;&lt;br /&gt;      ValidTo &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; to;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; Guid Id { get ...&lt;br /&gt;      set {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; (value == Guid.Empty)&lt;br /&gt;        { &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;throw&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; ArgumentException(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"FooEntity's Id attribute cannot be empty."&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"value"&lt;/span&gt;); }&lt;br /&gt;        _id &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; value;&lt;br /&gt;        Logger.Write(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Set FooEntity.Id"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"General"&lt;/span&gt;);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    [NotNullValidator]&lt;br /&gt;    [RegexValidator(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;@"^ [A-Z] [a-zA-Z0-9-_\.]{3,15} $"&lt;/span&gt;, RegexOptions.IgnorePatternWhitespace)]&lt;br /&gt;    [StringLengthValidator(4, RangeBoundaryType.Inclusive, 16, RangeBoundaryType.Inclusive)]&lt;br /&gt;nbsp;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; Name { ... }&lt;br /&gt;    [PropertyComparisonValidator(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"ValidTo"&lt;/span&gt;, ComparisonOperator.LessThanEqual)]&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; DateTime ValidFrom { ... }&lt;br /&gt;    [PropertyComparisonValidator(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"ValidFrom"&lt;/span&gt;, ComparisonOperator.GreaterThanEqual)]&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; DateTime ValidTo { ... }&lt;br /&gt;    [SelfValidation]&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;void&lt;/span&gt; ValidateThis(ValidationResults results) {&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; (_id == Guid.Empty) { ... }&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; (_from.Date !&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; _from) { ... }&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; (_to.Date !&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; _to) { ... }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;} &lt;/span&gt;&lt;/code&gt; 
&lt;P&gt;Teoretycznie aplikacja składa się z warstwy dostępu do danych, na której działa warstwa usług. W celu uproszczenia przykładu, baza danych została zastąpiona statycznym słownikiem na obiekty &lt;STRONG&gt;FooEntity&lt;/STRONG&gt;. Błędy dostępu do bazy danych symulują wyjątki pochodne klasy &lt;STRONG&gt;SystemException&lt;/STRONG&gt;.&lt;/P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;namespace&lt;/span&gt; ZineNet.PiabContest.Services {&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sealed&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;class&lt;/span&gt; FooService: IFooService {&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;static&lt;/span&gt; Dictionary&amp;lt;Guid, FooEntity&amp;gt; _data &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; ...;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; FooEntity GetById(Guid id) {&lt;br /&gt;      FooEntity e &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;null&lt;/span&gt;;&lt;br /&gt;      Logger.Write(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Before FooService.GetById"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"General"&lt;/span&gt;);&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;try&lt;/span&gt; {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; (id == Guid.Empty) { &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;throw&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; FakeSqlException(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Id column of Foo table cannot be empty."&lt;/span&gt;); }&lt;br /&gt;        e &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; _data[id];&lt;br /&gt;      } &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;catch&lt;/span&gt; (SystemException ex) {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; (ExceptionPolicy.HandleException(ex, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"WrapSystemExPolicy"&lt;/span&gt;)) {&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;throw&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;      Logger.Write(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"After FooService.GetById"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"General"&lt;/span&gt;);&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;return&lt;/span&gt; e;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; List&amp;lt;FooEntity&amp;gt; GetByNameStart(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; namePart) {&lt;br /&gt;      Logger.Write(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Before FooService.GetByNameStart"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"General"&lt;/span&gt;);&lt;br /&gt;      ...&lt;br /&gt;      Logger.Write(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"After FooService.GetByNameStart"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"General"&lt;/span&gt;);&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;return&lt;/span&gt; result;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; FooEntity Set(FooEntity value) {&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;try&lt;/span&gt; {&lt;br /&gt;        ValidationResults r &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; Validation.Validate(value);&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; (!r.IsValid) { &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;throw&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; FakeSqlException(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"FooEntity validation failed."&lt;/span&gt;); }&lt;br /&gt;      } &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;catch&lt;/span&gt; (SystemException ex) {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; (ExceptionPolicy.HandleException(ex, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"WrapSystemExPolicy"&lt;/span&gt;)) {&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;throw&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;      Logger.Write(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Before FooService.Set"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"General"&lt;/span&gt;);&lt;br /&gt;      ...&lt;br /&gt;      Logger.Write(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"After FooService.Set"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"General"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;void&lt;/span&gt; Remove(Guid id) {&lt;br /&gt;      Logger.Write(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Before FooService.Remove"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"General"&lt;/span&gt;);&lt;br /&gt;      ...&lt;br /&gt;      Logger.Write(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"After FooService.Remove"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"General"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;sealed&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;class&lt;/span&gt; FakeSqlException: SystemException {&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; FakeSqlException(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; message)&lt;br /&gt;        : &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;base&lt;/span&gt;(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"SQL Database Error: "&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;+&lt;/span&gt; message) {}&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;} &lt;/span&gt;&lt;/code&gt; 
&lt;P&gt;Konsumentem usług, a zarazem symulacją warstwy interfejsu użytkownika zajmuje się klasa &lt;STRONG&gt;EntryPoint&lt;/STRONG&gt;.&lt;/P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;namespace&lt;/span&gt; ZineNet.PiabContest {&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;class&lt;/span&gt; EntryPoint {&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;void&lt;/span&gt; Main() {&lt;br /&gt;      QuickTests();&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;try&lt;/span&gt; {&lt;br /&gt;        ExCallService();&lt;br /&gt;      } &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;catch&lt;/span&gt; (Exception ex) {&lt;br /&gt;        Console.WriteLine(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;" [EXCEPTION] "&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;+&lt;/span&gt; ex.Message);&lt;br /&gt;      }&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;try&lt;/span&gt; {&lt;br /&gt;        ExCallServiceSet();&lt;br /&gt;      } &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;catch&lt;/span&gt; (Exception ex) {&lt;br /&gt;        Console.WriteLine(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;" [EXCEPTION] "&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;+&lt;/span&gt; ex.Message);&lt;br /&gt;      }&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;try&lt;/span&gt; {&lt;br /&gt;        ExModifyEntity();&lt;br /&gt;      } &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;catch&lt;/span&gt; (Exception ex) {&lt;br /&gt;        Console.WriteLine(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;" [EXCEPTION] "&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;+&lt;/span&gt; ex.Message);&lt;br /&gt;      }&lt;br /&gt;      Console.ReadKey();&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;void&lt;/span&gt; QuickTests() { ... }&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;void&lt;/span&gt; ExCallService() { ... }&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;void&lt;/span&gt; ExModifyEntity() { ... }&lt;br /&gt;  }&lt;br /&gt;} &lt;/span&gt;&lt;/code&gt; 
&lt;P&gt;Użycie poszczególnych &lt;STRONG&gt;Application Block&lt;/STRONG&gt; polega na:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;VAB&lt;/STRONG&gt; – walidacja stanu obiektów &lt;STRONG&gt;FooEntity&lt;/STRONG&gt; – modelu danych. 
&lt;LI&gt;&lt;STRONG&gt;LAB&lt;/STRONG&gt; – logowanie zmian obiektów modelu danych oraz wywołań metod usług. 
&lt;LI&gt;&lt;STRONG&gt;EHAB&lt;/STRONG&gt; – osłona wyjątków z warstwy dostępu do danych oraz ukrycie szczegółów wyjątków przed użytkownikiem.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Diagram klas przykładowej aplikacji&lt;/P&gt;&lt;A href="http://zine.net.pl/photos/posts_pictures/images/543/original.aspx"&gt;&lt;IMG alt="Diagram klas przykładowej aplikacji" src="http://zine.net.pl/photos/posts_pictures/images/543/559x480.aspx"&gt;&lt;/A&gt; 
&lt;H3&gt;Definiowanie reguł i wytycznych&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;Reguły&lt;/STRONG&gt; określone przez architekturę systemu to:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Logowanie wywołań metod warstwy usług 
&lt;LI&gt;Logowanie zmian stanu modelu danych 
&lt;LI&gt;Osłona wyjątków warstwy dostępu do danych (symulowanych przez wyjątki pochodne &lt;STRONG&gt;SystemException&lt;/STRONG&gt;) 
&lt;LI&gt;Osłona wyjątków warstwy usług 
&lt;LI&gt;Osłona wyjątków modelu danych. 
&lt;LI&gt;Walidacja stanu modelu danych przekazywanych do warstwy usług&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Ponieważ interfejsy usług znajdują sie w jednej przestrzeni nazw wraz z innymi typami danych, możemy zdefiniować następującą &lt;STRONG&gt;wytyczną&lt;/STRONG&gt;:&lt;/P&gt;
&lt;P&gt;A. Każda metoda z każdego typu &lt;STRONG&gt;CLR&lt;/STRONG&gt; danych o nazwie &lt;STRONG&gt;IFooService&lt;/STRONG&gt; jest interesująca&lt;/P&gt;
&lt;P&gt;Zmiana stanu modelu danych może być monitorowana po przez przechwycenie wywołania metody set na odpowiedniej właściwości. Oznaczamy każdą metodę set właściwości nas interesującej tagiem o nazwie &lt;STRONG&gt;ZineNet.PiabContest&lt;/STRONG&gt;. Definiujemy następującą wytyczną:&lt;/P&gt;
&lt;P&gt;B. Każda metoda oznaczona tagiem o nazwie &lt;STRONG&gt;ZineNet.PiabContest&lt;/STRONG&gt; jest interesująca.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Reguły&lt;/STRONG&gt; 3, 4 i 6 definiują również poprzednią &lt;STRONG&gt;wytyczną&lt;/STRONG&gt; - A.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Reguła&lt;/STRONG&gt; 5 definiuje poprzednią &lt;STRONG&gt;wytyczną&lt;/STRONG&gt; – tym razem B.&lt;/P&gt;
&lt;H3&gt;Konfiguracja PIAB&lt;/H3&gt;
&lt;P&gt;Edytujemy plik konfiguracyjny przy użyciu znanego narzędzia &lt;STRONG&gt;Enterprise Library Configuration Editor&lt;/STRONG&gt;.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Dodajemy &lt;STRONG&gt;Policy Injection Application Block&lt;/STRONG&gt; 
&lt;LI&gt;W nim tworzymy dwie &lt;STRONG&gt;wytyczne&lt;/STRONG&gt; (Policy) o nazwach &lt;STRONG&gt;ByTagPolicy&lt;/STRONG&gt; i &lt;STRONG&gt;ServicePolicy&lt;BR&gt;&lt;IMG alt="Widok ogólny na konfigurację" src="http://zine.net.pl/photos/posts_pictures/images/534/original.aspx"&gt;&lt;/STRONG&gt; 
&lt;LI&gt;Do &lt;STRONG&gt;wytycznej&lt;/STRONG&gt; &lt;STRONG&gt;ByTagPolicy&lt;/STRONG&gt; dodajemy regułę dopasowania według &lt;STRONG&gt;TagAttribute&lt;/STRONG&gt; (Tag Attribute Matching Rule) i ustawiamy wartości następująco:&lt;BR&gt;&lt;IMG alt="Ustawienia dla wytycznej ByTagPolicy 1" src="http://zine.net.pl/photos/posts_pictures/images/535/original.aspx"&gt; 
&lt;LI&gt;Do &lt;STRONG&gt;wytycznej&lt;/STRONG&gt; &lt;STRONG&gt;ServicePolicy&lt;/STRONG&gt; dodajemy regułę dopasowania według typu &lt;STRONG&gt;CLR&lt;/STRONG&gt; (Type Matching Rule) i ustawiamy właściwości następująco:&lt;BR&gt;&lt;IMG alt="Ustawienia dla wytycznej ServicePolicy 1" src="http://zine.net.pl/photos/posts_pictures/images/536/original.aspx"&gt;&lt;BR&gt;Matches:&lt;BR&gt;&lt;IMG alt="Ustawienia dla wytycznej ServicePolicy 2" src="http://zine.net.pl/photos/posts_pictures/images/537/original.aspx"&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Kolejnym krokiem jest dodanie rodzaju obsługi (&lt;STRONG&gt;Handlers&lt;/STRONG&gt;) do &lt;STRONG&gt;wytycznych&lt;/STRONG&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Do &lt;STRONG&gt;wytycznej&lt;/STRONG&gt; &lt;STRONG&gt;ByTagPolicy&lt;/STRONG&gt; dodajemy obsługę logowania (*.Log) i wyjątków (*.Exception) – potrzebne dla reguł 2 i 5. Ustawiamy je w następujący sposób:&lt;BR&gt;&lt;IMG alt="Ustawienia dla wytycznej ByTagPolicy 2" src="http://zine.net.pl/photos/posts_pictures/images/538/original.aspx"&gt;&lt;BR&gt;&lt;BR&gt;&lt;IMG alt="Ustawienia dla wytycznej ByTagPolicy 3" src="http://zine.net.pl/photos/posts_pictures/images/539/original.aspx"&gt; 
&lt;LI&gt;Do &lt;STRONG&gt;wytycznej&lt;/STRONG&gt; &lt;STRONG&gt;ServicePolicy&lt;/STRONG&gt; dodajemy obsługę logowania (*.Log), wyjątków (*.Exception) i walidacji (*.Validation) – potrzebne dla reguł 1, 3, 4 i 6. Ustawiamy je w następujący sposób:&lt;BR&gt;&lt;IMG alt="Ustawienia dla wytycznej ServicePolicy 3" src="http://zine.net.pl/photos/posts_pictures/images/540/original.aspx"&gt;&lt;BR&gt;&lt;BR&gt;&lt;IMG alt="Ustawienia dla wytycznej ServicePolicy 4" src="http://zine.net.pl/photos/posts_pictures/images/541/original.aspx"&gt;&lt;BR&gt;&lt;BR&gt;&lt;IMG alt="Ustawienia dla wytycznej ServicePolicy 5" src="http://zine.net.pl/photos/posts_pictures/images/542/original.aspx"&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;H3&gt;Usunięcie istniejącego kodu Application Block&lt;/H3&gt;
&lt;P&gt;Usuwamy kod walidacji, logowania i przechwytywania wyjątków z klas &lt;STRONG&gt;FooService&lt;/STRONG&gt;, &lt;STRONG&gt;FooEntity&lt;/STRONG&gt; oraz &lt;STRONG&gt;EntryPoint&lt;/STRONG&gt;.&lt;/P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; FooEntity GetById(Guid id) {&lt;br /&gt;  FooEntity e &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;null&lt;/span&gt;;&lt;br /&gt;  Logger.Write(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Before FooService.GetById"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"General"&lt;/span&gt;);&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;try&lt;/span&gt; {&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; (id == Guid.Empty) { &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;throw&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; FakeSqlException(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"Id column of Foo table cannot be&lt;br /&gt;empty."&lt;/span&gt;); }&lt;br /&gt;      e &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; _data[id];&lt;br /&gt;  } &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;catch&lt;/span&gt; (SystemException ex) {&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; (ExceptionPolicy.HandleException(ex, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"WrapSystemExPolicy"&lt;/span&gt;)) {&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;throw&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  Logger.Write(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"After FooService.GetById"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;"General"&lt;/span&gt;);&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;return&lt;/span&gt; e;&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;string&lt;/span&gt; Name {&lt;br /&gt;    get { &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;return&lt;/span&gt; _name; }&lt;br /&gt;    set {&lt;br /&gt;    _name &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; value;&lt;br /&gt;