tag:blogger.com,1999:blog-89794608370904296552024-03-13T11:33:02.904+01:00Oskar at .NETOskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.comBlogger27125tag:blogger.com,1999:blog-8979460837090429655.post-28094453340496108542016-03-13T23:53:00.000+01:002016-03-14T08:57:08.031+01:00Moja nierelacja z WROC#<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-7JZLspY2goY/VuZuaSYj-KI/AAAAAAAAA3Q/DI4G1CC425Q9uA5hc8Q1qXHfUCvseeCOg/s1600/WP_20160310_0043.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://2.bp.blogspot.com/-7JZLspY2goY/VuZuaSYj-KI/AAAAAAAAA3Q/DI4G1CC425Q9uA5hc8Q1qXHfUCvseeCOg/s400/WP_20160310_0043.jpg" width="383" /></a></div>
<br />
<br />
<span style="font-family: "verdana" , sans-serif;">Nie bywam na konferencjach tak często jakbym chciał. Dlaczego? Myślę, że moim problemem jest nonkonformizm, przesadny indywidualizm. Będąc na konferencji trzeba się socjalizować. <span style="font-family: "verdana" , sans-serif;">Uprawiać n</span>etworking (<span style="font-family: "verdana" , sans-serif;">n</span>ie cierpię tego słowa). Jak już się tam jest to warto by było skorzystać z okazji i zagadać do prelegentów. Porozmawiać z niewidzianymi od dawna kolegami ze studiów. Powiedzieć parę razy "zgadamy się" i kilka "będziemy w kontakcie". Czy to problem? Nie. Czy jestem osobą zamkniętą? Nie. Wręcz przeciwnie.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"></span><br />
<a name='more'></a><span style="font-family: "verdana" , sans-serif;">Byłem kiedyś na szkoleniu z asertywności. Próbowałem zdobyć hajs z unii. Kto by nie chciał? Musiałem, byłem. Nie żałuję. Tam powiedziano mi, że wszystko to co powiem, przed ALE nie ma znaczenia. Jeśli nawet powiem, że jesteś zajebisty i dodam ALE to i tak wyjdzie, że jesteś gnojek. I tutaj chcę dodać właśnie takie nieśmiałe ALE. Takie magiczne słowo.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Jestem osobą otwartą, ALE raczej (raczej dodaję na zmiększenie tego magicznego słowa), nie z tych do przodu. Lubię ludzi tych co znam. W barze nie zagaduję do kobiet. Najpierw na film, potem może dopiero do kina. Nie czuję potrzeby przyjaźnić się z sąsiadami tylko dlatego, że mieszkają koło mnie. Jadąc pociągiem nie chcę słuchać pociągowych gaduł.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">No taki jestem co zrobić. Mam wątpliwość. Ona gdzieś głęboko we mnie siedzi. Nękające ambiwalentne uczucia. Niby nie chcę, a chcę. Niby nie przychodzę nigdy niezaproszony, ALE jednak czasem się wpraszam. Np. na WROC# (dzięki Ula!).</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Jednak czasem bywam, czasem się pojawiam na konferencjach. Co na nich szukam? Szukam dużo CJI. Pierwiastka CJI. Motywacji, inspiracji, kontemplacji. No i właśnie czy też integracji?</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Dzisiaj zdałem sobie sprawę z pewnego paradoksu. Prelegenci na konferencje przyjeżdżają słuchać, a uczestnicy mówić. Prelegenci chcieliby usłyszeć pochwały, a uczestnicy móc je wypowiedzieć.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">No i ja właśnie przychodzę na konferencje mówić. Trochę z kolegami (cheers <a href="http://mjendza.net/" target="_blank">Mateusz</a>, <a href="http://www.spacjer.com/" target="_blank">Rafał</a>!) , trochę z przygodnie poznanymi osobami. Czasem też i po to by móc koślawo przerwać Maćkowi Aniserowiczowi rozmowę, by podziękować za jego link w podsumowaniu miesiąca. No nie jestem <a href="http://www.dziennik.com/images/made/uploads/news/12713110_1024_1512_80.jpg" target="_blank">mistrzem pierwszego kroku</a>.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Człowiek w Internecie jest odważniejszy. W tym roku nawet pokusiłem się o lajftłiting</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;"><a class="twitter-timeline" data-widget-id="709132980304871427" href="https://twitter.com/search?q=from%3Aoskar_at_net%20since%3A2016-03-10%20until%3A2016-03-11%20include%3Aretweets">Tweets about from:oskar_at_net since:2016-03-10 until:2016-03-11 include:retweets</a>
</span><script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Konferencje są jak słuchanie dobrego rapu, musi być punchline. Można by szukać dobrego refrenu jak w piosence pop. Myśl przewodnia to sprawa kluczowa. Konsekwencja.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Co jeszcze? Nie szukam odpowiedzi jak, gdzie, kiedy? Szukam odpowiedzi po co i dlaczego. No i tak jak pisałem powyżej. Dużo CJI.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Czy WROC# miał dobry punchline? Czy miał swój tłusty bit? MC był zdecydowanie <a href="https://blog.rendle.io/" target="_blank">Mark Rendle</a>. <a href="http://blog.kokosa.net/" target="_blank">Konrad Kokosa</a> powiedział, że po jego prezentacji chce założyć startup. Ja też. W zasadzie to chciałem już wcześniej, ALE teraz tym bardziej. Była to właśnie taka prezentacja, gdzie ilość CJI była na najwyższym poziomie. Jakieś 237kg. Życiowe porady, wła<span style="font-family: "verdana" , sans-serif;">s</span>ne doświadczenia, konkretne sugestie. </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Czy inne miały dużo magicznego pierwiastka? Nie. Czy były powalające? Nie. ALE. ALE. ALE były konsekwentne. Była w nich jak w dobrej modlitwie mantra. Była myśl przewodnia i spójność. Czy to dobrze? Nie zawsze, ALE! ALE wszystko się ładnie składało. </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Najpierw <a href="http://megakemp.com/" target="_blank">Enrico Campidoglio</a> próbował nas namówić, że jak mówisz GIT to myślisz konsola.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Potem <a href="http://thedatafarm.com/" target="_blank">Julie Lerman</a> próbowała nieśmiało nas przekonać, że mimo niedorobienia, <a href="https://twitter.com/oskar_at_net/status/682238856805105667" target="_blank">Ejtiti Framework</a> w konsoli i na maku nie jest taki zły.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Na koniec <a href="https://channel9.msdn.com/Events/Speakers/glenn-condron" target="_blank">Glenn Condron</a> próbował nas przekonać, że nie jest tutaj po to by jako pracownik Microsoft zareklamować swoje produkty (mało wiarygodnie). </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Dodatkowo <a href="http://chris.59north.com/" target="_blank">Chris Klug</a> pokazał nam, że lepiej wypada, gdy ma problemy z komputerem, dociska łokciem kabel od odtwarzacza jednocześnie próbując pokazać nam jak zrobić swojego Angulara niż gdy próbuje nam pokazać przekrojówkę przez JavaScript. <a href="http://codebetter.com/iancooper/" target="_blank">Ian Cooper</a> pokazał z kolei, że lepiej wypada gdy nie musi pokazywać nam, że Mikroserwisy to nie Jednorożec i gdy może swobodnie rozmawiać przy piwku na panelu dyskusyjnym niż gdy przelatuje się po slajdach.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Czy pokochałem konsolę? Nie. Czy stałem się ewangelistą Mikroserwisów? Nie. Czy dowiedziałem się coś nowego o JavaScript? Nie.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">ALE. ALE.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">ALE i tak było warto. Czy mówiłem, że nie jestem lizusem? ALE i tak muszę pochwalić. To co mnie zauroczyło już drugi raz na WROC#. Organizację. Pisane z wielkiej litery. Jak moje imię.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">To co najbardziej szanuję to przywiązanie do detali. Profesjonalizm. Drobny gest, gifcik, o którym inni nie pomyślą. A tutaj było tego w bród. Pokal czy kufel z wygrawerowanym napisem konferencji. Szybkość reakcji nawet gdy klima lub mikrofon przestaje działać. Jedzenie nie będące jedynie przywiezionym na szybko kateringiem, a zrobionym show w wokach. Specjalne piwo, o którym potem się dowiaduję, że wybierając słabsze wybieram 9% piwko z Widawy. To, że dostaję dyskietkę lub kartę perforowaną jako identyfikator. Piękny dźwięk mikrostyku. Możliwość pokazania koleżance jak wygrać w Street Fightera grając </span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">odwróconym<span style="font-family: "verdana" , sans-serif;"> </span></span>plecami do automatu.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">To są drobne rzeczy, ale właśnie takie drobne rzeczy tworzą klimat konferencji. Prelegenci mogą nie trafić tematami, niektórzy mogą mieć gorszy dzień. Nie każdemu wszystko musi się podobać. ALE konferencja to nie tylko wykłady, to również cała otoczka, którą z jednej strony się unika, ALE która również przyciąga. To jest to co wyróżnia dobre konferencje od złych. To co decyduje o sukcesie. </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Pierwsza edycja WROC# była świetną niespodzianką, druga potwierdziła ważne miejsce na mapie polskich konferencji. Jaka będzie trzecia? Nie wiem, ALE nie mogę się doczekać, by przekonać się o tym w następnym roku.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">P.S. Zachęcam też do lektury innych relacji <a href="http://immora.azurewebsites.net/2016/03/wrocsharp-relacja/" target="_blank">Immora'y</a><span style="font-family: "verdana" , sans-serif;">,</span> <a href="http://programistka.net/wrocsharp-moja-relacja/" target="_blank">Iwony Lalik</a>, <a href="http://blog.softio.pl/2016/03/11/slowa-o-wrocsharp/" target="_blank">Dariusza Lenartowicza</a>, <a href="http://blog.klimczyk.pl/2016/03/12/wroc-2016-by-engineers-for-engineers/" target="_blank">Pawła Klimczyka</a> </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span></div>
</div>
Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com5tag:blogger.com,1999:blog-8979460837090429655.post-44280652646717786832016-01-06T22:07:00.001+01:002016-01-06T23:59:50.080+01:00Nauka uczenia (się)<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Człowiek uczy się całe życie. Słyszymy, powtarzamy ten truizm. Czasem jest to pochwała, najczęściej pocieszenie.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Wiedza, mądrość, inteligencja, czy to synonimy?</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Na studiach uczymy się czy studiujemy? Po studiach jesteśmy mądrzejsi czy mamy większą wiedzę?</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Czasami słyszę pytania skąd wiem to co wiem i w jaki sposób dowiaduję się co mam wiedzieć. Sam też często zadaję na rozmowach kwalifikacyjnych pytania: </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
<span style="font-family: Verdana,sans-serif;">"Skąd Pani/Pan czerpie wiedzę?"</span></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<span style="font-family: Verdana,sans-serif;">"Co Pani/Pan robi gdy natrafi na problem, z którym do tej pory się nie spotkała/ł"</span></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<span style="font-family: Verdana,sans-serif;">"Czy ma Pani/Pan jakieś może nie autorytety programistyczne ale po prostu ludzi na których odpowiedzi Pani/Pan często trafia?"</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Podsumowaniem odpowiedzi niech będzie miks:</span></div>
<div style="text-align: center;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: center;">
<span style="font-family: Verdana,sans-serif;">"No wie Pan, zwykle to jak wszyscy: StackOverflow, Google. A osoby? Eee... Raczej nie kojarzę teraz, najczęściej to po prostu szukam odpowiedzi i tyle"</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">A Ty mój drogi czytelniku, czego szukasz na tym blogu? Rozwiązania problemu? Inspiracji? Tak sobie klikasz? Skrolujesz?</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Sierpień 2007 roku był miesiącem, który nie zapisał się</span><span style="font-family: Verdana,sans-serif;"><span style="font-family: Verdana,sans-serif;"> wielce</span> na kartach historii, zaczął się jak każdy od 12 lat Przystankiem Woodstock. Przez Mikołajki przeszedł największy szkwał w historii. 46te urodziny obchodził pewien senator z Illinois. Wyszła pierwsza wersja jQuery. Gdzieś pomiędzy tymi wydarzeniami rozpoczął swoją zawodową karierę niżej podpisany blogger.</span><span style="font-family: Verdana,sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"></span></div>
<a name='more'></a><br />
<br />
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Wyszukiwanie
w Google nie było jeszcze takie oczywiste dla wszystkich. Gawiedź
ciągle jeszcze lubiła korzystać z wyszukiwarek na Onet, Interii i WP. W
portalach branżowych królowały CodeProject, CodeGuru. Cały MSDN
mieścił się na instalce Visual Studio.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Rok później, dokładnie 6 sierpnia Jeff Artwood <a href="http://blog.codinghorror.com/help-name-our-website/" target="_blank">poprosił </a>o pomoc w wyborze nazwy dla swojego startupu. W głosowaniu trzecie miejsce zajęła nazwa </span><span style="font-family: Verdana,sans-serif;"><span style="font-family: Verdana,sans-serif;"> dereferenced.com,</span> drugie </span><span style="font-family: Verdana,sans-serif;">privatevoid.com, wygrała stackoverflow.com.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Dzikie czasy.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Rzeka czasu płynie. Technologie się zmieniają. Popularność mija. Lustra się zmieniają - na tych nowszych człowiek jakoś tak starzej wygląda. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Nie wierzyłem kiedyś, że założę Twittera, do dzisiaj już naskrobałem 619 tweetów (i licznik <a href="https://twitter.com/oskar_at_net" target="_blank">bije</a>). </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span><span style="font-family: Verdana,sans-serif;">Ale wracając do pytania: jak zdobywam wiedzę? Czy jestem w tym oryginalny? Nieee. Pewnie to znasz, ale może coś jednak nowego podłapiesz.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;">Problemy dnia codziennego</span></span></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/NP4lrVIpbvo/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/NP4lrVIpbvo?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Nie wiem jak rozwiązać jakiś problem, leci mi bug, potrzebuję przykład implementacji. Who I gonna call? Google.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Booooring! </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Zacznijmy
od tego, że zawsze instaluję angielską wersję systemu oraz narzędzi z
których korzystam. Kiedyś zainstalowałem omyłkowo polskie wersje, przez
co musiałem najpierw wymyślać jak treść błędu brzmiałby po angielsku.
Wpisywać w google, próbować tłumaczyć to ponownie, bo pierwsza próba nie
była najlepsza. Nie muszę Wam mówić, jak kłopotliwą sprawą to było. </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Co charakteryzuje moje wyszukiwania? W przypadku błędu sprawdzam w debuggerze czy nie ma inner exception (zwykle ma więcej do zaoferowania). W wyszukiwarce </span><span style="font-family: Verdana,sans-serif;">wpisuję jego kod/numer i maksymalnie jedno zdanie z jego treści. Staram się wybrać ten fragment, który charakteryzuje najlepiej co się stało. Za długi opis ograniczy nam za bardzo listę wyników. Ważne, żeby nie wpisywać tekstu charakterystycznego dla naszego rozwiązania, czyli wyciąć np. nazwy naszych klas, nie wklejać numeru linii itd. itp.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Jakie strony uznaję zwykle za warte kliknięcia? Stack - wiadomo, MSDN - zwykle też, chociaż często brakuje tam opisu dlaczego, jest tylko jak, co bywa kłopotliwe. Blogi? Jak najbardziej. Code Project? Tak sobie. Niestety od czasu zmonopolizowania go przez Hindusów (no offence) strona poszła w ilość nie jakość. Czasem jednak da się dalej trafić na dobre artykuły. Fora internetowe i grupy dyskusyjne staram się klikać na końcu, jak już nic dobrego nie znajdę. To subiektywne, ale ciężko mi się w nich odnaleźć. Za dużo też tam dyskusji zaciemniających sytuację.</span><span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Nie
muszę dodawać, że ograniczanie się do samej pierwszej strony z wynikami
to błąd. Ja zwykle klikam dalej, póki widzę, że linki wydają mi się
sensowne. Gdy pojawią w wynikach linki zachęcające do obejrzenia cycków
Kasi Cichopek - czas znikać. </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">(Btw - zauważyliście też ten zalew spamerskich stron kradnących kliki treściami ze Stacka? Czemu gugiel nic z tym nie zrobi? Przecież Ceneo potrafili swego czasu wyciąć jednym sztychem...)</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Co robię gdy nie znajdę ni zadowalającego? Staram się znaleźć słowa kluczowe w odpowiedziach. Zwykle piszą je osoby, które lepiej znają język dziedzinowy ode mnie i warto wpisać fragment ich odpowiedzi w wyszukiwarkę.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Ważne, żeby nie ograniczać swojego wyszukiwania do pierwszym linku ze stacka, a już tym bardziej do najlepiej punktowanej odpowiedzi. Zwykle tylko z tych minusowych nie da się nic wartościowego dowiedzieć. </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Warto nie kończyć szukania nawet jak pierwsza odpowiedź wydaje się sensowna. Podobno lepsze jest wrogiem dobrego, ale nie w tym przypadku.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;">Źródła problemów</span></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">No i okej. Położyliśmy listek babki na bubę. Krew już nie leci. Skutki błędu usunięte. Można żyć dalej? Można. A potem człowiek idzie po tym samym chodniku, potyka się o tę samą płytę i znowu te samo kolano zdarte.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><u>Ważne, jest likwidować źródło problemu, a nie tylko sam problem</u> (Jasiu, możesz? Tak jest - wężykiem. Dziękuję). Jak zlikwidujemy źródło, to problem też przestanie występować. Wiadomo, krew trzeba zatamować szybko i bez zbędnych pytań, ale potem warto jednak sytuację przeanalizować.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Co więc jest tym źródłem problemu? Conradowskim jądrem ciemności? Najczęściej po prostu niewiedza, czasem lenistwo, czasem po prostu krótka pamięć. Jak można je wyeliminować?</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Krótka pamięć? Robienie notatek, zapisywanie linków w posegregowanych w foldery zakładkach, zapisywanie sobie kodów źródłowych z przykładami w jednym miejscu. Z dobrze nazwanymi i pogrupowanymi katalogami</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Lenistwo? Ruszenia dupy.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Niewiedza? Jak powtarzała moja germanistka: Uczitsa, Uczitsa, Uczitsa.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Jak ja podchodzę konkretnie do tematu? No cóż, mieszam wszystkie trzy rzeczy w jedną. Gdy szukam rozwiązania problemu zapisuję sobie znalezione linki jako zakładki (tak aby mi nie przepadły). Co więcej, te które uznam za wartościowe zostawiam otwarte. Kończy się to zwykle kilkudziesięcioma zakładkami i Firefoxem zżerającym ponad giga ramu. Ale co tam, o to chodzi. Im bardziej irytuje tym bardziej nie daje o sobie zapomnieć. Samo zapisanie linku bez zostawienia niestety powoduje, że krótka pamięć i myślenie "a dobra to jutro go otworzę" zaczyna działać. </span><span style="font-family: Verdana,sans-serif;">Najlepsze linki staram się też wrzucać na Twittera.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Zwykle te zapisane linki są potem źródłem do kolejnych poszukiwań. Szukam na blogach, szukam w książkach. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Nie samym Internetem człowiek żyje. Warto zapytać też kolegów czy natrafili na podobny problem, jak go rozwiązali. Dobrze jest nawet zagaić na zasadzie:</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">"Jasiu, patrz jaki jestem zajebisty, zobacz jaki kawał kodu napisałem", </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Wtedy często trafiamy na ripostę:</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">"No pięknie, ładnie. Super to zrobiłeś - tylko po co? Wiesz, że jest biblioteka X co zrobi to za Ciebie?"</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Ego cierpi, wiedza rośnie.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">W skrócie - warto być dociekliwym, ciekawskim, nawet czasem upierdliwym.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: Verdana,sans-serif;">GPS</span></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Na początku chciałem być programistą Javy, uwielbiałem Eclipse. C# i Visual Studio wydawały mi się takie sobie. Dostałem się jednak na staż w .NET, spodobało mi się i przez taki pół-przypadek wyznaczyłem sobie azymut, którym podążam do do dzisiaj. Nie była to oczywista decyzja, w między czasie zarabiałem też na pisaniu aplikacji we Flashu, Ruby. Większość ofert pracy we Wrocławiu była w Javie lub C++, a te co były to zwykle w małych firmach.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Flash umarł, Java się zagubiła w rozwoju, kierunek okazał się na szczęście dobry, ale praca w innych technologiach dała mi sporo dobrego. Dzięki Javie szybko nauczyłem się C#, Flashowi asynchroniczności, Ruby wzorca MVC.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Sama praca w technologiach Microsoftu też była jak jazda rollercoasterem:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- ASP.NET WebForms,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- ASP.NET MVC (beta!) </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- Win.Forms,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- MVVM w WPF,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- ASP.NET MVC z koniecznością zostania specem od JavaScript,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- Business Inteligence w MSSQL bez frontendu</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"> </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Niby środowisko te same, a technologie kompletnie inne. Co ja będę Wam mówił, macie pewnie podobnie. Taka dola programisty. Ciężko się do czegoś przyzwyczajać. Można i trzeba wyznaczyć sobie kierunek. Meandrów się jednak nie uniknie. Co więcej nie warto chyba tego robić.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Jak żyć gdy technologie tak szybko się zmieniają? Gdy wzorce szybko robią się nieaktualne, a frameworki JavaScriptowe szybko robią się takie zeszłotygodniowe. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Co bym radził:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- trzymać rękę na pulsie, </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- zachować zdrowy rozsądek,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- być otwartym na nowe technologie, nie łapiąc jednocześnie podjarki każdym nowym frameworkiem</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- nie zasklepiać się w swoich poglądach i dobrze znanych rozwiązaniach.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Czyli być optymistycznym sceptykiem. Zamkniętym w sobie gadułą. Najlepiej schizofrenikiem. To pomaga.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Tak, wiem "<a href="https://www.youtube.com/watch?v=mBS0OWGUidc" target="_blank">Show me the money!</a>". Czy moją tajemnicą jest bycie schizofrenikiem? Mój niewidzialny kolega mówi, że nie (uch, tak suche, że muszę popić... sorry).</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Co robię? Tak jak już mówiłem, staram się szukać, analizować, zapisywać sobie linki i czytać wpisy na temat tego co mnie zaciekawi. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Szukam innych sposobów jakie ludzie mieli na rozwiązanie mojego problemu. Wychwytuję słowa kluczowe, które rzucają. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Nawet w głupich odpowiedziach gdy ktoś szuka rozwiązania w C#, a ktoś pisze "e stary, daj spokój zrób to w tym frameworku w Javie" jest dobre źródło inspiracji. Warto kliknąć, przeczytać ogólnie co to jest, zapamiętać - zasadzić ziarno. </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Gdy jakieś hasło powtórzy się wystarczająco dużo razu to uznaję, że warto mu się przejrzeć dokładnie.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Co jeszcze? Tak jak wspominałem, warto rozmawiać z kolegami, dopytywać się innych znajomych co robią, jakich technologii używają, czy mają jakieś rozwiązania, którymi mogą się pochwalić. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Dobrymi miejscami na tego typu rozmowy są spotkania różnych grup tematycznych - w każdym dużym mieście jest Grupa .NET. Udział w konferencjach zawsze też zostawia jakieś dobre obserwacje, inspiracje. Warto co najmniej raz/dwa w roku wybrać się. Zobaczyć, posłuchać, pogadać. Ważne jednak, żeby z tym nie przesadzić i nie traktować głosów tam usłyszanych jako prawdy objawionej. Niestety konferencyjna społeczność często ociera się lekko o zamknięte towarzystwo wzajemnej adoracji. U prelegentów często też zauważam, że im więcej jeżdżą po konferencjach, a mniej pracują zawodowo to tym częściej głoszą oderwane od szarej rzeczywistości tezy. Warto pójść, posłuchać, przemyśleć, ale trzeba zachować zdrowy krytycyzm.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Innym, może nieco zaskakującym źródłem są dla mnie zapytania, które dostaję na LinkedIn, GoldenLine. Mogę po nich zobaczyć jaki zestaw umiejętności szukają pracodawcy. Wiadomo, należy na to patrzeć przez palce, ale jest to w pewnym sensie miernik, co akurat w innych firmach jest modne. To też nieco kontrowersyjne, ale wg mnie warto też raz na jakiś czas pójść na rozmowę kwalifikacyjną. Pomijając samą kwestię zmiany pracy, daje to nam obraz czy przypadkiem </span><span style="font-family: Verdana,sans-serif;"><span style="font-family: Verdana,sans-serif;">"</span>nie zardzewieliśmy" i czego nam brakuje.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;">Prawo Jazdy</span></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">No i ok, masz już zebrane wszystkie pomysły, inspiracje. Przesiałeś, wyselekcjonowałeś, nakreśliłeś priorytety. Co dalej? </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Wiadomo, najlepiej użyć ich w swoich projektach w pracy B-)</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.kappit.com/img/pics/201409_2339_hfifa_sm.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://www.kappit.com/img/pics/201409_2339_hfifa_sm.jpg" height="200" width="200" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">To nie jest dobry pomysł. To tak jak próbować otworzyć nóż sprężynowy nie wiedząc gdzie jest przycisk. Auć! Może się udać, ale jak się nie uda to efekt opłakany. Poza tym czy to na pewno etyczne wydawać pieniądze klientów na naszą fanaberię nauki nowej technologii, gdzie stara by mu styknęła?</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Ja zwykle staram się przeczytać porcję blogów, książek, zaimplementować sobie samemu proof of concept. Jeśli się po nich okaże, że ma szansę to pomóc mojemu projektowi, albo wprowadzenie tej zmiany nie będzie dużym kosztem , a w przyszłości może zaowocować np. łatwiejszym jego utrzymaniem to też rozważam jego użycie.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Tak jak pisałem w innym wpisie - <a href="http://oskar-at-net.blogspot.com/2015/01/borys-najlepiej-dryblowa.html" target="_blank">często wymyślam sobie projekty, których potem nie kończę</a>. Zwykle wymyślam je, bo zainspirowała mnie jakaś technologia, dla której znalazłem świetne (w moim mniemaniu) zastosowanie. To smutne, że te projekty się nie udają, ale fajne, że uczę się dużo nowych rzeczy, które potem przydają mi się w kolejnych projektach.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Jak szukam książek? To akurat proste. Szukam na Amazon.com. Wpisuję słowo kluczowe, które mnie interesuje i patrzę na opinię. Prawie zawsze zgadzam ze średnią ocen i opinii, które tam są zamieszczane. Warto szukać książek z jak największą liczbą ocen, jak najnowszych, czytać kilka opinii, zarówno tych negatywnych jak i pozytywnych. No ale to wiecie. Co potem? Często kupuję książkę i czytam ją na Kindle. 100zł</span><span style="font-family: Verdana,sans-serif;"><span style="font-family: Verdana,sans-serif;"> na dobrą książkę</span> raz na jakiś czas to wg mnie dobra inwestycja.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Ewentualnie zaglądam na: <a href="http://it-ebooks.info/" target="_blank">http://it-ebooks.info/</a> lub <a href="http://ebookee.org/" target="_blank">http://ebookee.org/</a>. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Nie czytam polskich wersji, bo tłumaczenia zwykle są kiepskie. Polskie wersje kluczowych terminów i zwrotów utrudniają dalsze poszukiwania zagadnień.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">No i mam ulubione blogi, ludzie których podpatruję. Oni się zmieniają w zależności od tego co aktualnie jest u mnie na topie, oraz od tego w jakiej formie są ich autorzy. Postaram się w innym wpisie wrzucić moje zestawienie.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: Verdana,sans-serif;">Piona na drogę</span></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">No i tak to u mnie wygląda. Nic wielce odkrywczego, nic wielce trudnego. Tajemnica to trochę otwartości, szczypta ciekawości i odrobina samozaparcia.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Warto przesuwać swoje granice, warto czasem wyjść z pudełka i zobaczyć co jest na zewnątrz.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Tak jak w odchudzaniu wystarczy mówić jedno słowo: </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">"Nie!"</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">tak w uczeniu w zasadzie </span><span style="font-family: Verdana,sans-serif;"><span style="font-family: Verdana,sans-serif;">wystarczy powtarzać notorycznie</span>:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><u><b>Dlaczego?</b></u> <span style="font-size: x-small;"> </span></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><span style="font-size: xx-small;">(tak Jasiu, wężykiem)</span></span><br />
<br />
<br />
<span style="font-family: Verdana,sans-serif;"><span style="font-size: xx-small;"><span style="font-size: small;">p.s. a Ty mój drogi czytelniku jak się uczysz uczyć? Wszelkie komentarze porady z Twojej strony mile widziane!</span></span></span></div>
</div>
Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com6tag:blogger.com,1999:blog-8979460837090429655.post-13219433867040403642015-12-07T21:48:00.000+01:002015-12-07T23:02:25.316+01:00Cierpienia niemłodego bloggera - czyli próbuję napisać tekst o wczytywaniu komponentów w Knockout.JS na podstawie konwencji nazewniczej. Wymyślając przy okazji najdłuższy wpis w historii tego bloga. Doh! -_-<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Życie bloggera to nie jest bułka z szynką. To nie prosta sprawa. Co prawda pomysły same wpadają <span style="font-family: "verdana" , sans-serif;">do głowy. <span style="font-family: "verdana" , sans-serif;">I</span></span>dzie człowiek ulicą, drepcze tak sobie drepcze i nagle bęc, nagle bum! Albo koduje sobie taki, wymyśla rozwiązanie i myśli sobie<span style="font-family: "verdana" , sans-serif;">: O!</span> <span style="font-family: "verdana" , sans-serif;">T</span>o świetny temat na blog<span style="font-family: "verdana" , sans-serif;">!</span> Warto się nim podzielić! Tylko potem to jakoś tak ciężko przelać na papier. Siada sobie Pan Redaktor. Zabiera się za spisanie sw<span style="font-family: "verdana" , sans-serif;">y</span>ch wiekopomnych odkryć. Herbata stygnie, zapada zmrok a pod klawiaturą ciągle nic, obowiązek obowiązkiem jest, wpis musi posiadać tekst.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">No i siadam. Klasyczne pytania. Jak zacząć? Jak Ciebie nie zanudzić, mój drogi czytelniku? Ej człowieku, pisz tam lepiej. Nie mazgaj się i tak piszesz dla siebie. Ale, ale... jak? To przecież nie ma być kolejny suchy<span style="font-family: "verdana" , sans-serif;">, i</span>rytujący wpis jakich pełno w blogosferze. Chyba mnie grypa bierze...</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Tyle rzeczy do przekazania... Tyle rzeczy do powiedzenia...</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Może wspomnieć, że jest mi smutno, że Knockout.JS przegrał już jakiś czas temu walkę z Angularem? Albo, że wg mnie nie powinno się przenosić wprost backendowych wzorców do zupełnie innego środowiska JavaScriptu? </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Wspomnieć o tym, że nie mam zaufania do React? Że kojarzy mi się z programowaniem WinFormsowym? Hmmm...</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br />A może po prostu wejść na pełnej k... i powiedzieć od razu, że mam świetną klasę, którą nazwałem <a href="https://github.com/oskardudycz/Knockout.ComponentByNamingConventionLoader/blob/master/src/content/Scripts/ComponentByNamingConventionLoader.js" target="_blank">ComponentByNamingConventionLoader</a>? I że bierzcie i jedzcie z tego wszyscy? Dodać, że jeśli używacie Knockout.JS to na pewno Wam się przyda? Eeee... to jakoś nie wygląda... (Siorb) Ej! Herbata już całkiem zimna...</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">A może wrócić do podstaw? Może <a href="http://www.bryk.pl/jak_pisa%C4%87/rozprawka" target="_blank">rozprawkę</a>? Wprowadzenie, teza, argument <span style="font-family: "verdana" , sans-serif;">pie<span style="font-family: "verdana" , sans-serif;">rw</span></span>szy, <span style="font-family: "verdana" , sans-serif;">dru</span>gi, <span style="font-family: "verdana" , sans-serif;">trze</span>ci, <span style="font-family: "verdana" , sans-serif;">czwar</span>ty, potwierdzenie tezy</span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">, podsumowanie</span>. Ma to sens. Ma to sens. Wszystko byle już wreszcie zacząć. Ołówek, notatnik i jadziem kapela.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"></span><br />
<a name='more'></a><span style="font-family: "verdana" , sans-serif;"></span>
<b><span style="font-family: "verdana" , sans-serif;">Teeeee-za:</span></b></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Warto jest pisać modularne aplikacje w Knockout. Warto też ułatwić sobie przy tym życie używając mechanizmu komponentów oraz konwencji nazewniczych.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Wężykiem Jasiu, wężykiem.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;"><b>Ar-gu-ment 1</b>:</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Knockout jest tylko i aż frameworkiem MVVM. To zaleta. Jest prosty i dzięki temu bardzo elastyczny. Dlaczego piłka nożna jest tak popularna? Bo ma proste zasady. Nawet Twoja dziewczyna wie co to spalony. Knockout nie ogranicza programisty, daje możliwość łatwej rozbudowy, łączenia z innymi bibliotekami. Np. dodając Sammy.JS i Require.JS mamy praktycznie lżejszego Angulara. Używając go nie musimy się zapisywać do sekty, w każdym momencie możemy <span style="font-family: "verdana" , sans-serif;">go wymienić</span>. </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Gdzie ja dałem tę temperówkę... O jest.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<b><span style="font-family: "verdana" , sans-serif;">Argu-ment 2:</span></b></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Modularność jest cool. Kiedyś myślałem, że generyczność. Naaah. Przyjdźcie na wystawę LEGO<span style="font-family: "verdana" , sans-serif;">,</span> na wrocławski stadion<span style="font-family: "verdana" , sans-serif;">,</span> to zobaczycie dlaczego (jest i rym a'la Rychu Peja). Podział aplikacji na moduły daje aplikacji skalowalność, łatwość rozwoju, ponownego wykorzystania kodu. Chcesz dorzucić kilka sposobów logowania? Żaden problem, zamienić jeden widok <span style="font-family: "verdana" , sans-serif;">z </span>drugim? Keine problem! Wpiąć zestaw Robin Hooda do zestawu Ninja<span style="font-family: "verdana" , sans-serif;">g</span>o<span style="font-family: "verdana" , sans-serif;">?</span> Też się da.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b><span style="font-family: "verdana" , sans-serif;">Ar-gu-meeent 3:</span></b></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Komponenty w Knockout pozwalają <span style="font-family: "verdana" , sans-serif;">tworzyć </span>frontend w pełni modułowo. </span><span style="font-family: "verdana" , sans-serif;">Czym one w ogóle są? <span style="font-family: "verdana" , sans-serif;">P</span>owiązanym ze sobą <span style="font-family: "verdana" , sans-serif;">W</span>idokiem i ViewModelem. Czyli pakiecikiem, który dostarcza zarówno logik<span style="font-family: "verdana" , sans-serif;">ę</span> biznesow<span style="font-family: "verdana" , sans-serif;">ą</span> jak i format<span style="font-family: "verdana" , sans-serif;">ę</span> j<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">ą</span> </span>obsługując<span style="font-family: "verdana" , sans-serif;">ą</span> - 2w1, Head&Shoulders. <span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">P</span></span>owiązanie luźne jak nadgarstek nastolatka. Zgodne z zasadami SOLID. W dalszym ciągu widok nie musi za dużo wiedzieć o ViewModelu<span style="font-family: "verdana" , sans-serif;">. I</span> z wzajemnością. <span style="font-family: "verdana" , sans-serif;">N<span style="font-family: "verdana" , sans-serif;">ie ma problemu z <span style="font-family: "verdana" , sans-serif;">uży<span style="font-family: "verdana" , sans-serif;">waniem tych samych</span> <span style="font-family: "verdana" , sans-serif;">widok<span style="font-family: "verdana" , sans-serif;">ów i <span style="font-family: "verdana" , sans-serif;">viewmodeli <span style="font-family: "verdana" , sans-serif;">w różnych</span> komponenta<span style="font-family: "verdana" , sans-serif;">ch</span>.</span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Już <span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">trzy</span></span>? <span style="font-family: "verdana" , sans-serif;">T</span>o mało<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">?</span> <span style="font-family: "verdana" , sans-serif;">D</span>użo<span style="font-family: "verdana" , sans-serif;">? <span style="font-family: "verdana" , sans-serif;">A </span></span><span style="font-family: "verdana" , sans-serif;">może w</span> sam<span style="font-family: "verdana" , sans-serif;"> raz</span></span>? W zasadzie każdy z <span style="font-family: "verdana" , sans-serif;">argumentów </span>to
temat na osobny wpis. <span style="font-family: "verdana" , sans-serif;">Może <span style="font-family: "verdana" , sans-serif;">je napisać najpierw</span>? <span style="font-family: "verdana" , sans-serif;">E<span style="font-family: "verdana" , sans-serif;">c<span style="font-family: "verdana" , sans-serif;">h<span style="font-family: "verdana" , sans-serif;">, ech.</span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;"><b>Ar-gument 4:</b></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">A po co ta moja wspaniała klasa skoro Knockout sam w sobie taki fajny? Komponenty w Knockout <span style="font-family: "verdana" , sans-serif;">daje nam</span> domyśln<span style="font-family: "verdana" , sans-serif;">y </span>prost<span style="font-family: "verdana" , sans-serif;">y</span> i z grubsza spoko mechanizm wczytywania komponentów. Dodatkowo <span style="font-family: "verdana" , sans-serif;">jego t</span>wórcy<span style="font-family: "verdana" , sans-serif;"> d</span>ali <span style="font-family: "verdana" , sans-serif;">nam m</span>ożliwość zmiany domyślnego mechanizmu, poprzez zdefiniowanie i podpięcie własnej klasy loadera.</span>
<span style="font-family: "verdana" , sans-serif;">Po co to robić? <span style="font-family: "verdana" , sans-serif;">A np. dlate<span style="font-family: "verdana" , sans-serif;">go, że m</span>nie.</span><span style="font-family: "verdana" , sans-serif;">:</span></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">- <span style="font-family: "verdana" , sans-serif;">n</span>ie podoba się domyślna definicja kom<span style="font-family: "verdana" , sans-serif;">ponentu przez podanie anonimowej klasy i kodu html bezpośrednio w defni<span style="font-family: "verdana" , sans-serif;">cji komponentu</span></span></span></span></div>
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">ko.components.register('login-component', {
viewModel: function(params) {
this.username = ko.observable();
this.password= ko.observable();
this.login = function() { /* Login Logic */ };
},
template:
'<input data-bind="text: username" type="text" />
<input data-bind="text: password" type="password" />
<button data-bind="click: login ">Log in!</button>'
});</pre>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">- nie podoba mi się również altern<span style="font-family: "verdana" , sans-serif;">atywna wersja<span style="font-family: "verdana" , sans-serif;">, w której <span style="font-family: "verdana" , sans-serif;"></span></span></span>muszę umieszcza<span style="font-family: "verdana" , sans-serif;">ć</span> w ciele html głównej strony definicji widoku pomiędzy znacznikami <template><span style="font-family: "verdana" , sans-serif;"> i </span>muszę pamiętać, żeby załączyć plik z klasą viewmodelu do strony, lub co gorsza zdefiniować klasę na tej stronie.</span></div>
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;"><template id="login-view">
<input data-bind="text: username" type="text" />
<input data-bind="text: password" type="password" />
<button data-bind="click: login ">Log in!</button>
</template>
<script>
function LoginViewModel(params){
this.username = ko.observable();
this.password= ko.observable();
this.login = function() { /* Login Logic */ };
}
ko.components.register('login-component', {
viewModel: LoginViewModel,
template: { element: 'login-view' },
});
</script>
</pre>
<br />
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Mam drobnomieszczańskie zwyczaje, ciepła woda w kranie, te sprawy. Ja to bym chciał po prostu podać nazwę komponentu, a niech już mechanizm sam sobie zaciągnie odpowiedni widok i viewmodel. Najlepiej po konwencji nazewniczej i najlepiej z odpowiedniego katalogu. </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Przykładowo chcę wyświetlić komponent: Login. </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Czy nie byłoby fajn<span style="font-family: "verdana" , sans-serif;">e gdyby </span>Knockout sam sobie zaczytał:</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">- widok LoginView z lokalizacji: Scripts/Components/Login/LoginView.html,</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">- viewmodel LoginViewModel z lokalicacji: Scripts/Components/Login/LoginViewModel.js?</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Jak to zrobić? Użyć mojej wspaniałej klasy B-)</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Uf. </span>T<span style="font-family: "verdana" , sans-serif;">o argumenty mam za sobą<span style="font-family: "verdana" , sans-serif;">.<span style="font-family: "verdana" , sans-serif;"> Co tam następne w planie rozprawki? <span style="font-family: "verdana" , sans-serif;">Ach, wiem<span style="font-family: "verdana" , sans-serif;">.</span></span></span></span></span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><b>Potw<span style="font-family: "verdana" , sans-serif;">ierdzenie tez<span style="font-family: "verdana" , sans-serif;">y</span></span></b></span></span></span></span></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Co teraz? Detaliczny opis? Nudny listing<span style="font-family: "verdana" , sans-serif;">?</span> <span style="font-family: "verdana" , sans-serif;">Może <span style="font-family: "verdana" , sans-serif;">kod </span>po prostu wkleić? N<span style="font-family: "verdana" , sans-serif;">iech <span style="font-family: "verdana" , sans-serif;">czytelnik ma szaradę. A<span style="font-family: "verdana" , sans-serif;"> może wzorem Makłowicza pokazać<span style="font-family: "verdana" , sans-serif;">, że wystarczy <span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">wymyślić <span style="font-family: "verdana" , sans-serif;">nazwę klasy, dopisać jedną metodę, <span style="font-family: "verdana" , sans-serif;">odczekać <span style="font-family: "verdana" , sans-serif;">chwilę i </span>mamy <span style="font-family: "verdana" , sans-serif;">gotową klasę na ponad <span style="font-family: "verdana" , sans-serif;">100 linii kodu?<span style="font-family: "verdana" , sans-serif;"> <span style="font-family: "verdana" , sans-serif;">Wszystkiego po trochu?</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Aby <span style="font-family: "verdana" , sans-serif;">przeładowa<span style="font-family: "verdana" , sans-serif;">ć <span style="font-family: "verdana" , sans-serif;">Knockoutowy mechaniz<span style="font-family: "verdana" , sans-serif;">m <span style="font-family: "verdana" , sans-serif;">loaderów <span style="font-family: "verdana" , sans-serif;">komponentów należy </span></span></span></span></span>utworzyć klas<span style="font-family: "verdana" , sans-serif;">ę <span style="font-family: "verdana" , sans-serif;">zawierającą następuj<span style="font-family: "verdana" , sans-serif;">ące metody:</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">- </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">loadTemplate<span class="pl-k"> - gdy chcemy prz<span style="font-family: "verdana" , sans-serif;">eład<span style="font-family: "verdana" , sans-serif;">ować <span style="font-family: "verdana" , sans-serif;">mechanizm pobierania <span style="font-family: "verdana" , sans-serif;">widoku</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">- </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">loadViewModel<span class="pl-k"> - gdy chcemy przeł<span style="font-family: "verdana" , sans-serif;">adować mechanizm pobierani<span style="font-family: "verdana" , sans-serif;">a viewmodelu</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">- <span style="font-family: "verdana" , sans-serif;">getConfig<span style="font-family: "verdana" , sans-serif;"> - gdy chcemy przeładować wszystko. W<span style="font-family: "verdana" , sans-serif;">-s<span style="font-family: "verdana" , sans-serif;">-z-y-s-t<span style="font-family: "verdana" , sans-serif;">-k-o.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">P</span>otem <span style="font-family: "verdana" , sans-serif;">wystarczy taką klasę zarejestrować. Przykładzik:</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">function ComponentByNamingConventionLoader(){
this.loadTemplate = function(name, templateConfig, callback){
// Logic
}
this.loadViewModel = function(name, viewModelConfig, callback){
// Logic
}
this.config = function(name, callback){
// Logic
}
}
ko.components.loaders.unshift(new ComponentByNamingConventionLoader());</pre>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div style="text-align: justify;">
<b><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Założenia <span style="font-family: "verdana" , sans-serif;">moje<span style="font-family: "verdana" , sans-serif;">go loadera </span>są <span style="font-family: "verdana" , sans-serif;">tak jak wspom<span style="font-family: "verdana" , sans-serif;">niałem:</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></b></div>
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">1. <span style="font-family: "verdana" , sans-serif;">Dać możliwość<span style="font-family: "verdana" , sans-serif;"> zaczytywania komponentów wg konwencji nazewniczych bez konieczności ich rejestracji<span style="font-family: "verdana" , sans-serif;">.<span style="font-family: "verdana" , sans-serif;"> Ma to da możliwość eleganckiego rozbicia na osobne pliki i wygodę użycia<span style="font-family: "verdana" , sans-serif;">.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">2. Mechanizm ma dalej pozwalać na użycie klasycznego <span style="font-family: "verdana" , sans-serif;">sposobu używania <span style="font-family: "verdana" , sans-serif;">Knockouta.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">3. <span style="font-family: "verdana" , sans-serif;">Dodajemy też możliwość <span style="font-family: "verdana" , sans-serif;">zdefiniowania pobierania<span style="font-family: "verdana" , sans-serif;"> <span style="font-family: "verdana" , sans-serif;">widoków i <span style="font-family: "verdana" , sans-serif;">viewmodeli <span style="font-family: "verdana" , sans-serif;">z zadanego urla.</span></span></span></span></span></span> </span></span> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"> </span></span> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Zatem do dzieła. Do ko<span style="font-family: "verdana" , sans-serif;">du!</span> Jak mówił Linus <span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">T</span>orvalds</span>: <span style="font-family: "verdana" , sans-serif;">"<a href="https://lkml.org/lkml/2000/8/25/132" target="_blank">Talk is cheap. Show me the code.</a>".</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><b><span style="font-family: "verdana" , sans-serif;">GetConfig</span></b></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Metoda <span style="font-family: "verdana" , sans-serif;">przyjmuje dwa parametry<span style="font-family: "verdana" , sans-serif;">: nazwę<span style="font-family: "verdana" , sans-serif;"> <span style="font-family: "verdana" , sans-serif;">komponentu i callback, który wywoł<span style="font-family: "verdana" , sans-serif;">a mechanizmy <span style="font-family: "verdana" , sans-serif;">Knockouta do <span style="font-family: "verdana" , sans-serif;">da<span style="font-family: "verdana" , sans-serif;">lszego pro<span style="font-family: "verdana" , sans-serif;">cesowania konfiguracji. F<span style="font-family: "verdana" , sans-serif;">unkcja najpier<span style="font-family: "verdana" , sans-serif;">w sprawdza czy w ogóle powinna używać konwencji nazewniczej czy<span style="font-family: "verdana" , sans-serif;"> nie<span style="font-family: "verdana" , sans-serif;">. J</span>eśli nie, to wywo<span style="font-family: "verdana" , sans-serif;">łuje domyślny mechanizm<span style="font-family: "verdana" , sans-serif;"> w przeciw<span style="font-family: "verdana" , sans-serif;">nym razie <span style="font-family: "verdana" , sans-serif;">odpala<span style="font-family: "verdana" , sans-serif;"> wczytywanie komponentów </span></span><span style="font-family: "verdana" , sans-serif;">ze <span style="font-family: "verdana" , sans-serif;">zmod<span style="font-family: "verdana" , sans-serif;">yfikowan<span style="font-family: "verdana" , sans-serif;">ą konfiguracją<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"> podając ścieżkę do pliku na bazie konwencji nazewniczej.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">(W ogóle to przerzucę się na <span style="font-family: "verdana" , sans-serif;"><a href="https://gist.github.com/" target="_blank">Gista</a>. Na<span style="font-family: "verdana" , sans-serif;">wet w połowie </span>wpisu, trochę to niekonse<span style="font-family: "verdana" , sans-serif;">kwentne, ale on <span style="font-family: "verdana" , sans-serif;">jest taki słodki</span> <<span style="font-family: "verdana" , sans-serif;">3 Ja<span style="font-family: "verdana" , sans-serif;">k <span style="font-family: "verdana" , sans-serif;">kocha to poczeka, jasne, jak kocha<span style="font-family: "verdana" , sans-serif;"> to <span style="font-family: "verdana" , sans-serif;">nie wytrzyma <span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">po</span>czekać)</span></span></span></span></span></span></span></span> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><b><span style="font-family: "verdana" , sans-serif;"> </span></b> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<script src="https://gist.github.com/oskardudycz/6b4eed53d6c165f372c8.js"></script>
</div>
<div style="text-align: justify;">
<br /></div>
<b><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">LoadViewModel</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></b><br />
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Metoda przyjmuje trzy parametry<span style="font-family: "verdana" , sans-serif;">:</span> nazwę <span style="font-family: "verdana" , sans-serif;">komponentu</span><span style="font-family: "verdana" , sans-serif;">, obiekt z konfiguracją <span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">V</span>iew<span style="font-family: "verdana" , sans-serif;">M</span>odelu<span style="font-family: "verdana" , sans-serif;"> oraz <span style="font-family: "verdana" , sans-serif;">callback. <span style="font-family: "verdana" , sans-serif;">Obiekt z konfiguracją będzie wyglądał<span style="font-family: "verdana" , sans-serif;"> </span></span></span> np. <span style="font-family: "verdana" , sans-serif;"> </span></span></span></span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">{name: <span style="font-family: "verdana" , sans-serif;">'Name<span style="font-family: "verdana" , sans-serif;">OfAClass<span style="font-family: "verdana" , sans-serif;">'} </span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">lub w naszym przypadku <span style="font-family: "verdana" , sans-serif;"> </span></span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: left;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">{ <span style="font-family: "verdana" , sans-serif;">fromUrl</span>: '<span style="font-family: "verdana" , sans-serif;">/Scripts/<span style="font-family: "verdana" , sans-serif;">Compon<span style="font-family: "verdana" , sans-serif;">ents/<span style="font-family: "verdana" , sans-serif;">ComponentNam<span style="font-family: "verdana" , sans-serif;">e/ComponentNameView<span style="font-family: "verdana" , sans-serif;">Model<span style="font-family: "verdana" , sans-serif;">'}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Zasad<span style="font-family: "verdana" , sans-serif;">a działania jest analogiczna jak GetConfig<span style="font-family: "verdana" , sans-serif;">. Sprawdzamy czy <span style="font-family: "verdana" , sans-serif;">powinniśmy w ogóle używać konwencji nazewniczych<span style="font-family: "verdana" , sans-serif;"> czy nie i w za<span style="font-family: "verdana" , sans-serif;">leżności od tego<span style="font-family: "verdana" , sans-serif;"> wywołujemy domyślne <span style="font-family: "verdana" , sans-serif;">z<span style="font-family: "verdana" , sans-serif;">achowanie lub nasze zaczytywanie z pliku.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<br />
<script src="https://gist.github.com/oskardudycz/bb4bb58d7733abb65e63.js"></script>
<br />
<div style="text-align: justify;">
<br />
<b><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;">L</span>oadTemplate</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></b></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en">No tego to nie będę tłumacz<span style="font-family: "verdana" , sans-serif;">ył.<span style="font-family: "verdana" , sans-serif;"> Analogicznie jak <span style="font-family: "verdana" , sans-serif;">LoadViewModel <span style="font-family: "verdana" , sans-serif;">tylko dla pliku html.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<br />
<script src="https://gist.github.com/oskardudycz/ddbdb819e3da5aa64eba.js"></script>
<br />
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en">Jak widać sam <span style="font-family: "verdana" , sans-serif;">algo<span style="font-family: "verdana" , sans-serif;">rytm jest bardzo prosty i zrobiony przez analogię<span style="font-family: "verdana" , sans-serif;">. <span style="font-family: "verdana" , sans-serif;">Dobra Makłowi<span style="font-family: "verdana" , sans-serif;">cz, a jak w<span style="font-family: "verdana" , sans-serif;">ygl<span style="font-family: "verdana" , sans-serif;">ądają implementacje kluczowych metod? Niewiele trudniej<span style="font-family: "verdana" , sans-serif;">.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<br />
<b><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">LoadViewFromUrl</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></b><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Dzięci<span style="font-family: "verdana" , sans-serif;">o</span>ł jaki jest każdy widzi. Preparujemy url<span style="font-family: "verdana" , sans-serif;"> poprzez dodanie prefi<span style="font-family: "verdana" , sans-serif;">ksu do ścieżki i <span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">sufiksu z ustawieniami cache'owania <span style="font-family: "verdana" , sans-serif;">strony (<span style="font-family: "verdana" , sans-serif;">w celach optym<span style="font-family: "verdana" , sans-serif;">alizacji)</span></span><span style="font-family: "verdana" , sans-serif;">. Potem wywołujemy <span style="font-family: "verdana" , sans-serif;">pob<span style="font-family: "verdana" , sans-serif;">ranie pliku poprzez <span style="font-family: "verdana" , sans-serif;">jQuery<span style="font-family: "verdana" , sans-serif;">'owy <span style="font-family: "verdana" , sans-serif;">$.get, a <span style="font-family: "verdana" , sans-serif;">pobrany html </span>wstrzy<span style="font-family: "verdana" , sans-serif;">kujemy </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>do <span style="font-family: "verdana" , sans-serif;">K</span>nockouta przy pomocy <span style="font-family: "verdana" , sans-serif;">wbud<span style="font-family: "verdana" , sans-serif;">owanej metody<span style="font-family: "verdana" , sans-serif;">. Jeśli coś <span style="font-family: "verdana" , sans-serif;">poszło nie tak -</span><span style="font-family: "verdana" , sans-serif;"> wywołujemy domyślny mechanizm.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<br />
<script src="https://gist.github.com/oskardudycz/50882716e8536f35fd19.js"></script>
<br />
<b><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">LoadViewModelFromUrl</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></b><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Metoda jest bardzo zbliżona do wczyt<span style="font-family: "verdana" , sans-serif;">ywania widoku</span>, z tym, że <span style="font-family: "verdana" , sans-serif;">zamiast zwykłego $.get używamy <a href="http://stackoverflow.com/a/23435602" target="_blank">zmodyfikowanej metody </a><span style="font-family: "verdana" , sans-serif;"><a href="http://stackoverflow.com/a/23435602" target="_blank">$.getScript - <span style="font-family: "verdana" , sans-serif;">$.cachedScrip<span style="font-family: "verdana" , sans-serif;">t</span></span></a><span style="font-family: "verdana" , sans-serif;">, która pozwala zaciągnąć <span style="font-family: "verdana" , sans-serif;">kod JS<span style="font-family: "verdana" , sans-serif;"> z zewnętrznego pliku i wczytać <span style="font-family: "verdana" , sans-serif;">go do przeglądarki (używając przy t<span style="font-family: "verdana" , sans-serif;">ym cache<span style="font-family: "verdana" , sans-serif;">)</span></span>. </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Potem są robione dwa tri<span style="font-family: "verdana" , sans-serif;">ki:</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">- </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-c1">window</span>[<span class="pl-en">getViewModelNameFromUrl</span>(<span class="pl-smi">options</span>.<span class="pl-smi">relativeUrl</span>)] - pobieranie kons<span style="font-family: "verdana" , sans-serif;">t<span style="font-family: "verdana" , sans-serif;">ruktora </span>klasy <span style="font-family: "verdana" , sans-serif;">ViewModelu po jego nazwie. W Java<span style="font-family: "verdana" , sans-serif;">Script wszystkie <span style="font-family: "verdana" , sans-serif;">definicje klas są dostępne jako propertiesy, można się <span style="font-family: "verdana" , sans-serif;">odwołać do niego poprzez klasyczny indekser na obiekcie <span style="font-family: "verdana" , sans-serif;">okna<span style="font-family: "verdana" , sans-serif;"> - </span></span>np. <span style="font-family: "verdana" , sans-serif;">window["<span style="font-family: "verdana" , sans-serif;">LoginViewModel"]</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">- drugi trick to metoda </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en">viewModelInitialization</span><span style="font-family: "verdana" , sans-serif;">, która <span style="font-family: "verdana" , sans-serif;">tworzy nam najpierw obiekt <span style="font-family: "verdana" , sans-serif;">ViewModelu (na bazie zaczyt<span style="font-family: "verdana" , sans-serif;">anego konstruktora)<span style="font-family: "verdana" , sans-serif;">. S</span></span>prawdza <span style="font-family: "verdana" , sans-serif;">czy<span style="font-family: "verdana" , sans-serif;"> m<span style="font-family: "verdana" , sans-serif;">a on dostępną metodę "init"<span style="font-family: "verdana" , sans-serif;">. Jeśli ma to pozwala <span style="font-family: "verdana" , sans-serif;">uruchamia ją z przesłanymi </span> parametrami<span style="font-family: "verdana" , sans-serif;">. Taki ficzer.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<br />
<script src="https://gist.github.com/oskardudycz/b9781c11f6350a06d737.js"></script>
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">No<span style="font-family: "verdana" , sans-serif;"> i<span style="font-family: "verdana" , sans-serif;"> to by było na tyle. Reszta to proste metody pomocnicze<span style="font-family: "verdana" , sans-serif;">. Chcesz je zobaczyć<span style="font-family: "verdana" , sans-serif;">? A może pełen kod? Kliknij</span></span> <span style="font-family: "verdana" , sans-serif;"><a href="https://github.com/oskardudycz/Knockout.ComponentByNamingConventionLoader/blob/master/src/content/Scripts/ComponentByNamingConventionLoader.js" target="_blank">tu, no kliknij</a><span style="font-family: "verdana" , sans-serif;">.</span></span></span></span></span> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://stream1.gifsoup.com/view7/2488138/please-sir-i-want-some-more-o.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://stream1.gifsoup.com/view7/2488138/please-sir-i-want-some-more-o.gif" /></a></div>
<br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Podoba Ci się<span style="font-family: "verdana" , sans-serif;"> i<span style="font-family: "verdana" , sans-serif;"> chciałbyś to użyć</span></span></span> w swoim pro<span style="font-family: "verdana" , sans-serif;">jekcie<span style="font-family: "verdana" , sans-serif;">?</span> <span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">P</span>obie<span style="font-family: "verdana" , sans-serif;">rz</span> <a href="https://www.nuget.org/packages/Knockout.ComponentByNamingConventionLoader/" target="_blank">nugeta</a>. Autor nawet nieś<span style="font-family: "verdana" , sans-serif;">miało zachęca do krytyki i pull requestów.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">No i<span style="font-family: "verdana" , sans-serif;"> niby rozprawka cała<span style="font-family: "verdana" , sans-serif;">, podsumowani<span style="font-family: "verdana" , sans-serif;">a tylko brak. </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Wpis taki długi, o<span style="font-family: "verdana" , sans-serif;">zdobników tak wiele<span style="font-family: "verdana" , sans-serif;">, pewnie się znudzili, <span style="font-family: "verdana" , sans-serif;">pewnie wymiękli. A chciałoby się wytrwały<span style="font-family: "verdana" , sans-serif;">ch zapytać czy wie<span style="font-family: "verdana" , sans-serif;">rzą już <span style="font-family: "verdana" , sans-serif;">reda<span style="font-family: "verdana" , sans-serif;">ktorowi</span></span>:</span></span></span></span></span></span></span></span><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">- </span></span></span></span></span></span></span></span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">że </span></span></span></span></span></span></span></span>komponenty w Knockout <span style="font-family: "verdana" , sans-serif;">pozwalają robić fajny,<span style="font-family: "verdana" , sans-serif;"> modularn<span style="font-family: "verdana" , sans-serif;">y <span style="font-family: "verdana" , sans-serif;">frontend</span></span></span>, </span></span></span></span></span></span></span></span></span><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">- że są łatw<span style="font-family: "verdana" , sans-serif;">e w użyciu, </span></span></span></span></span></span></span></span></span></span><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">- że faktycznie <span style="font-family: "verdana" , sans-serif;">ułat<span style="font-family: "verdana" , sans-serif;">wiają pracę<span style="font-family: "verdana" , sans-serif;">, a sam <span style="font-family: "verdana" , sans-serif;">Knockout <span style="font-family: "verdana" , sans-serif;">pozwala się <span style="font-family: "verdana" , sans-serif;">łatwo rozszerzać,</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">-<span style="font-family: "verdana" , sans-serif;"> </span>że użycie<span style="font-family: "verdana" , sans-serif;"> <span style="font-family: "verdana" , sans-serif;">wymyślonej przez niego klasie może się czyt<span style="font-family: "verdana" , sans-serif;">elnikowi przydać w ułożeniu kodu i przyspieszeniu developmen<span style="font-family: "verdana" , sans-serif;">tu.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Nawet jak<span style="font-family: "verdana" , sans-serif;">by przecząc<span style="font-family: "verdana" , sans-serif;">o pokręci<span style="font-family: "verdana" , sans-serif;">ł</span> głową to <span style="font-family: "verdana" , sans-serif;">można by się </span></span></span>nieśmiało obronić gar<span style="font-family: "verdana" , sans-serif;">ścią linków<span style="font-family: "verdana" , sans-serif;">:</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<div style="text-align: left;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">- <a href="http://knockoutjs.com/documentation/component-binding.html">http://knockoutjs.com/documentation/component-binding.html</a></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<div style="text-align: left;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">- <a href="http://knockoutjs.com/documentation/component-loaders.html">http://knockoutjs.com/documentation/component-loaders.html</a></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<div style="text-align: left;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">-<span style="font-family: "verdana" , sans-serif;"> </span><a href="http://www.knockmeout.net/2014/06/knockout-3-2-preview-components.html">http://www.knockmeout.net/2014/06/knockout-3-2-preview-components.html</a> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<div style="text-align: left;">
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">- <a href="https://javascriptkicks.com/articles/2657/i-wont-be-using-angular-for-my-next-project-and-neither-should-you">https://javascriptkicks.com/articles/2657/i-wont-be-using-angular-for-my-next-project-and-neither-should-you</a> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
<br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Pisać nie pisać? <span style="font-family: "verdana" , sans-serif;">Publikować nie publikować<span style="font-family: "verdana" , sans-serif;">? </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Rzucę monet<span style="font-family: "verdana" , sans-serif;">ą.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br />
<br />
<span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-en"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">Orzeł.</span> </span> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span class="pl-k"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"> </span></span> </span></span></span> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span> </span></div>
<span style="font-family: "verdana" , sans-serif;"> </span></div>
Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com2tag:blogger.com,1999:blog-8979460837090429655.post-63065779819785193712015-10-31T21:29:00.001+01:002015-12-07T22:55:35.888+01:00What really grind my gears #1 - IIIIIIIIIIIIIIIIF!<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-Mjo07Ipn-ks/VjUTOebeKaI/AAAAAAAAAy8/R_3vKX-Atto/s1600/what-really-grid-my-gears.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="http://2.bp.blogspot.com/-Mjo07Ipn-ks/VjUTOebeKaI/AAAAAAAAAy8/R_3vKX-Atto/s320/what-really-grid-my-gears.jpg" width="320" /></a></div>
<br />
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Jestem spokojnym człowiekiem, niespotykanie spokojnym. Ale... Jestem Oskar, z Polski. Miejsca urodzenia nie przeskoczę. Natura, historia, zwyczaje, pierogi, kierpce, Szopen wieczorową porą. </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">I irytacja. </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Rosnąca irytacja. </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Pulsująca irytacja. </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Przechodząca w krótkie, staropolskie słowo rozpoczynające się i kończące się na W.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">No co ja na to poradzę? Po prostu wiele rzeczy mnie denerwuje. Co np.? To, że gdy chcę jeździć na rowerze to jest za gorąco albo pada deszcz. To, że po piciu wódki na drugi dzień boli głowa. To, że studentów tyle w pociągach i to, że po każdej niedzieli przychodzi poniedziałek. Co ja będę Wam mówił, <a href="https://youtu.be/nNhrzGLdEVE?t=36s" target="_blank">nie jest łatwo być Polakiem</a>. Wicie rozumicie, wina Tuska.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Ciężko być Polakiem, ale być Polakiem i programistą to już tylko ciężej być kibicem i sprzedawcą butów (oh wait...). Te porażki w piłkarzyki w pracy, te przymusowe przerwy od przeglądania memów, gdy nam każą popracować. Ta dojmująca, nieznośna lekkość bytu. </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">I IFy. </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">IIIIIIFY. </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">KŁIIII KŁIII KŁIIIIIIIIIIIFY. </span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-o1yh-BiXrlU/UbfTe2P4_HI/AAAAAAAAAMk/51GCSTBvEwo/s1600/le-cochon-danseur-1907-vaudeville-pathc3a9-frc3a8res.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="234" src="http://1.bp.blogspot.com/-o1yh-BiXrlU/UbfTe2P4_HI/AAAAAAAAAMk/51GCSTBvEwo/s1600/le-cochon-danseur-1907-vaudeville-pathc3a9-frc3a8res.jpg" width="320" /></a></div>
<br />
<a name='more'></a><br />
<br />
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Mała.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Prosta.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Rzecz.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Programistyczna.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Ala.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Ma.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Kota. </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Kot.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Ma.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Alę.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">A ja jestem wmotylanogawiony. </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Hej Ty! Tak, Ty! </span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Do Ciebie wołam Przyjacielu! Ty, który robisz mi takie rzeczy:</span></div>
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public TwojTyp IIIIIIIIIIIIIIIIIFunkcja(JeszczeInnyTyp obj)
{
TwojTyp wynik;
if (obj != null)
{
if (obj.Nazwa == "Jakastam")
{
wynik = new TwojTyp(3);
}
else
{
int ilestam = wyliczIlestam(obj);
wynik = new TwojTyp(ilestam);
}
}
else
{
wynik = null;
}
return wynik;
}
</pre>
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "verdana" , sans-serif;">Doktor Ratajczak nie jest z Ciebie dumny. Ja nie jestem z Ciebie dumny. Czy ten kod naprawdę jest wg Ciebie czytelny? Czy tylko na tyle Cię stać?</span><br />
<br />
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">No dobra 10...9...8...7...6...5...4...3...2...1...0. Spokój. Oskar też tak pisałeś. I(IIIIIIII) to ile razy. Z Ciebie </span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">też </span>dr R nie był dumny.</span></div>
<br />
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Taki kod jest niestety czymś zupełnie powszechnym. Niestety jest też czymś zupełnie złym. Zwykle w </span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;">tych ifach i elsach </span>znajduje się co najmniej kilkunastoliniowa logika biznesowa. Zwykle nie mieści się <a href="http://www.kyhumane.org/images/articles/dorothy-totosm.jpg" target="_blank">to to na ekranie</a>. Taki kod nie da się czytać od góry do dołu. Nie da się szybko ocenić co tak naprawdę ta metoda zwraca, jaki jest oczekiwany wynik, jakie są skrajne przypadki. Zwykle chcąc zrozumieć co ta funkcja robi, trzeba przejść IF po I(IIIIIII)Fie, ELSE po ELSE, linijka po linijce. Zwykle scrollując, góra dół, dół góra. Płacz i zgrzytanie zębów.</span></div>
<br />
<span style="font-family: "verdana" , sans-serif;">Kod nie dość, że jest nieczytelny to jest</span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"> jeszcze</span> klasycznym czasopochłaniaczem, zdecydowanie nie czasoumilaczem, ale za to klientapieniądzoprzeżuwaczem. </span><br />
<br />
<span style="font-family: "verdana" , sans-serif;">Jak go poprawić? Bardzo prosto: </span><br />
<br />
<b><span style="font-family: "verdana" , sans-serif;">1. Stosuj odwrócone IFy.</span></b><br />
<b><span style="font-family: "verdana" , sans-serif;">2. Jak najszybciej zwracaj wartość.</span></b><br />
<b><span style="font-family: "verdana" , sans-serif;">3. Tnij i rezygnuj jak tylko można z używania ELSE.</span></b><br />
<b><span style="font-family: "verdana" , sans-serif;">4. Skrajne przypadki dawaj na początku, oczekiwane na końcu.</span></b><br />
<br />
<span style="font-family: "verdana" , sans-serif;">Odwracanie IF plus zwracanie jak najszybciej wartości (</span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><i>Angard!</i>)</span>:</span><br />
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public TwojTyp IIIIIIIIIIIIIIIIIFunkcja(JeszczeInnyTyp obj)
{
TwojTyp wynik;
if (obj == null)
{
return null;
}
else
{
if (obj.Nazwa == "Jakastam")
{
wynik = new TwojTyp(3);
}
else
{
int ilestam = wyliczIlestam(obj);
wynik = new TwojTyp(ilestam);
}
}
return wynik;
}
</pre>
<span style="font-family: "verdana" , sans-serif;"></span><br />
<span style="font-family: "verdana" , sans-serif;">Ucinanie ELSE (</span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><i>Touche!</i>)</span>:</span>
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public TwojTyp IIIIIIIIIIIIIIIIIFunkcja(JeszczeInnyTyp obj)
{
TwojTyp wynik;
if (obj == null)
{
return null;
}
if (obj.Nazwa == "Jakastam")
{
wynik = new TwojTyp(3);
}
else
{
int ilestam = wyliczIlestam(obj);
wynik = new TwojTyp(ilestam);
}
return wynik;
}
</pre>
<br />
<span style="font-family: "verdana" , sans-serif;">No i znowu i znowu (</span><span style="font-family: "verdana" , sans-serif;"><span style="font-family: "verdana" , sans-serif;"><i>Adieu!</i>)</span>:</span><br />
<span style="font-family: "verdana" , sans-serif;"> </span>
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public TwojTyp IIIIIIIIIIIIIIIIIFunkcja(JeszczeInnyTyp obj)
{
if (obj == null)
{
return null;
}
if (obj.Nazwa == "Jakastam")
{
return new TwojTyp(3);
}
int ilestam = wyliczIlestam(obj);
return new TwojTyp(ilestam);
}
</pre>
<br />
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Nie było tak trudno chyba, co? Paluszki nie zabolały? A główka? Och ^_^</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Taki kod jest dużo łatwiejszy do przeczytania. Na początku widzimy skrajne wartości, na końcu wynik ostateczny, a pomiędzy - logikę biznesową. Chcąc zrozumieć funkcję czytamy ją od góry do dołu, jak Pana Tadeusza, jak ten wpis o irytacji. Tak jak nasz mózg by chciał to widzieć. Czytelność, konwencja, prostota.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">No i nie irytuje.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Jest miło.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Spokojnie.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif;">Cichutka letnia bryza. </span></div>
<div style="text-align: justify;">
<br />
<span style="font-family: "verdana" , sans-serif;">Nikt nie krzyczy:</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif; font-size: x-large;">IIIIIIIIIIIIIIIIIIIIIF! </span></div>
</div>
Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com2tag:blogger.com,1999:blog-8979460837090429655.post-84833808810348875242015-03-29T14:36:00.000+02:002015-12-07T22:59:49.195+01:00Englishman in New York, czyli jak .NETowiec może uwić sobie gniazdko w świecie MSSQL<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">Wieczór, herbata, ciepłe papcie, nie za twardy, nie za miękki narożnik, na którym wyciągasz swoje zmęczone nogi. Gdzieś w tle leniwie snuje się muzyczka plum plum plum... Cieplutko, mięciutko, strefa komfortu. Mmmmm... Klawo!</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">Gdy tak sobie leżysz w apogeum czilałtu muzyka przestaje nagle grać, idąc sprawdzić o co chodzi zahaczasz nogą i wyrywasz kabel sieciowy, potem przepala Ci się bezpiecznik od światła, a z kranu zaczyna ciec woda. Tyle było twojego komfortu...</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">Jedziesz na tydzień na narty do Czech. Niby wszyscy mili, niby podobny język, ale jednak jakoś tak dziwnie. Uśmiechy wydają się coraz bardziej ukradkowe. Po złożeniu zamówienia w </span><span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">restauracji do ostatniej chwili drżysz czy faktycznie zamówiłeś to co chciałeś. </span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">Albo dajmy na to delegacja do Wałbrzycha lub Sosnowca...</span><br />
</div>
<div style="text-align: justify;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://31.media.tumblr.com/tumblr_m2id90CiW01r76lino1_500.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://31.media.tumblr.com/tumblr_m2id90CiW01r76lino1_500.gif" height="162" width="320" /></a></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br />
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">Praca programisty daleka jest od błogostanu. Nowy dzień, nowe problemy. Pudełko czekoladek prosto od Foresta. Szczególną sytuacją jest zmiana projektu. Konsternacja sięga zenitu. Nowe osoby, nowe środowisko i te parszywe nowe technologie.</span></div>
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">
</span>
<br />
<div style="text-align: justify;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><i>"...you can hear it in my accent when I talk, I'm an Englishman in New York"</i></span></span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">Jakiś czas temu doświadczyłem takiej zmiany. Drastyyycznej zmiany. Z intensywnej pracy przy mocno JavaScriptowym systemie przeszedłem na drugą stronę. Ciemniejszą stronę. Tam gdzie nie ma frontendu - systemu Business Inteligence w MSSQL.</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br />
<span style="font-family: "arial";"><i>"First I was afraid, I was petrified<b>"</b></i></span><br />
<span style="font-family: "arial";"><i><b> </b></i> </span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: "arial";">Nie tylko Ty się tak czułaś moja droga <a href="https://www.youtube.com/watch?v=Faf1ch7Q9XE" target="_blank">Glorio</a>.</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br />
<span style="font-family: "arial"; font-size: large;">Suma wszystkich strachów</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br />
<span style="font-family: "arial";">Czego się obawiałem?</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: "arial";"><b>1.</b> Management Studio jest przyzwoitym środowiskiem do zarządzania bazą danych. Z funkcjonalnościami i rozbudowaniem Visual Studio nie ma jednak żadnego porównania. Ot taki mniej rozgarnięty koleżka. Ten co nosi za duże, używane rzeczy po starszym bracie.</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: "arial";"><b>2.</b> Skryptów inkrementalnych. Każdy z nas wie jak bolesne jest utrzymywanie tego barachła. Oczywiście można sobie radzić, stosować konwencje nazewnicze, używać migracji w Entity Framework, ale czy to czyni sprawę przyjemną? Don't think so... Znośniejszą. W najlepszym razie. Dodajmy jeszcze do tego konieczność utrzymywania aktualnej struktury bazy, by można było zawsze odtworzyć ją od zera, kontrolę wersji i pracę na wielu branchach. Mniam. Mniam. Paluszki lizać.</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: "arial";"><b>3.</b> Wdrażania na różne środowiska. Developerskie, Testowe, Preprod, Produkcjne, NaKolejneZyczenieKlienta. I każde z tych środowisk się trochę różni, na każdym trzeba trochę inne skrypty odpalić. Kup sobie chłopcze zapas melisy jeśli chcesz być wdrożeniowcem, wujo Ci to mówi. Jeden Cherry pick, drugi cherry pick, zapomnisz przerzucić jeden skrypt inkrementalny i <a href="http://i.imgur.com/XxCqMiG.gif" target="_blank">KA BOOM!</a> Nie ma Cię - ehę. Albo produkcji. Twoja premia też gdzieś się zapodziała.</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: "arial";"><b>4.</b> Struktura i modularność projektu. Jak ładnie utrzymywać strukturę projektu w świecie MSSQL. Podział kodu, modularność, biblioteki, współdzielenie kodu przez różne projekty? Czy to w ogóle możliwe? Projekty w Management Studio, w porównaniu do tych znanych z VS to właśnie te spodnie starszego brata, które podcięto, żeby robiły za bojówki. Do tego kod się nie kompiluje, jak być pewnym, że po zmianie nazwy kolumny nie zapomnieliśmy poprawić kodu, w którejś procedurze? Jak być pewnym, że nasz projekt jest dalej stabilny?</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: "arial";"><b>5.</b> No i na koniec duszki Kacperki w porównaniu z poprzednimi punktami. Czyli takie fanaberie jak intellisence, refactoring, sprawdzanie gdzie używana jest procedura, tabela, przystępniejsze debugowanie kodu. Małe rzeczy, które czynią nas szczęśliwszymi. </span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br />
<span style="font-family: "arial"; font-size: large;">SSDT To the Rescue!</span><br />
<span style="font-family: "arial"; font-size: large;"></span><br />
<a name='more'></a><br /><span style="font-family: "arial";">Cóż to za enigmatyczny skrót i jak on może nam pomóc? Otóż SSDT to nic innego jak <a href="https://msdn.microsoft.com/en-us/data/tools.aspx" target="_blank">SQL Server Data Tools</a>. Jest to dodatek (czy też nakładka) do Visual Studio rozbudowująca jego możliwości w zakresie zarządzania, obsługi baz danych.</span></div>
<div style="text-align: justify;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">Czy rozwiewa którąś z moich obaw? </span><br />
<div style="font-size: 3px;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">No wiadomo, że tak, przecież bym o nim nie wspominał...</span></div>
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";">No to jedziemy po kolei Panie Dzieju:</span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";"><b>Ad.1</b> SSDT Pozwala robić dokładnie te same operacje co w Management Studio, nie każąc nam przy tym porzucać Visual Studio. Odpalanie zapytania, debuggowanie, operacje administacyjne. Możemy korzystajać przy tym z dobrodziejstw VS (choćby z tak prozaicznej rzeczy jak przyklejenie pliku zawsze na wierzchu - rzecz niewykonalna w Management Studio).</span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";"><b>Ad. 2 i 3</b> SSDT oparty jest na deklaratywnym modelu programowania baz danych. Uh, jak to mądrze brzmi. Czy również takie jest? <a href="http://latentflip.com/imperative-vs-declarative/" target="_blank">Są różne opinie</a>. </span><br />
<span style="font-family: "arial";">Deklaratywne programowanie jest to mówienie, że chcemy żeby zadziała się pewna rzecz, a nie mówienie wprost jak ma być to zrobione. Różnica między deklaratywnym a imperatywnym, jest taka jak pomiędzy poleceniem "Wyrzuć śmieci", a "wyciągnij worek, zejdź po schodach, podejdź do śmietnika i wrzuć go do kontenera".</span><br />
<span style="font-family: "arial";">Jedno i drugie ma swoje plusy. Mówienie konkretnie co masz zrobić bywa lepsze, ale zakłada, że wydający polecenia zna się na tym lepiej niż je wykonujący. Niby może być idiotoodporne, ale i tak kończy się zawsze: "Dlaczego nie włożyłeś nowego worka?!".</span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";">Lub tym:</span><br />
<span style="font-family: "arial";"></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/YiwxQKy.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/YiwxQKy.gif" height="219" width="320" /></a></div>
<br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";">No dobra zapędziłem się. W teorii mogę teraz napisać wszystko, bo pewnie nikt już tego nie czyta... Gdyby jednak, to wracając do tematu, deklaratywne programowanie oznacza w tym wypadku, że przygotowujemy po prostu definicje obiektów (tabel, procedur, itd.), a Visual Studio robi za nas skrypty różnicowe w trakcie wywołania publikacji projektu. Porównuje, przygotowuje i uaktualnia.</span><br />
<span style="font-family: "arial";">Czy to działa? Zaskakujące, ale tak.</span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";"><b>Ad. 4</b> SSDT dostarcza nam bazodawowe typy projektów. Możemy je referencjować między sobą, łączyć w solucje, mieszać z innymi typami projektów. Jest nawet coś w stylu bibliotek dll - pliki Dacpac. Możemy sobie zatem np. stworzyć projekty Common zawierający obiekty, które zawsze robimy tak samo (np. zarządzanie użytkownikami, logowanie, itd. itp) i dołączać je do swoich projektów. </span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";"><b>Ad. 5</b> Tutaj też dostajemy sporo fajnych usprawnień tj. zmiana nazw obiektów w obrębie całej solucji, bardziej rozbudowany intellisense, debugowanie, wyszukiwanie referencji itd. itp.</span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial"; font-size: large;">Yay or nay?</span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";">Czy jest to rewolucja? </span><br />
<span style="font-family: "arial";">Nie bardzo. </span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";">Czy jest to coś co sprawi, że życie bazodanowca będzie bułką z szynką? </span><br />
<span style="font-family: "arial";">Też nie bardzo. </span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";">Czy jestem tak happy pracując z bazami danych jak Pharell Williams? </span><br />
<span style="font-family: "arial";">No też nie do końca.</span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";">Jestem jednak dużo szczęśliwszy niż mógłbym być pracując w inny sposób. SSDT pozwala znacząco zwiększyć komfort pracy, uporządkować, usystematyzować, poukładać sobie ładnie w szufladeczkach. </span><br />
<span style="font-family: "arial";">Deklaratywne programowanie i posiadanie zwykłego rodzaju projektów daje nam możliwość fajnej integracji z systemami kontroli wersji oraz zrobienia porządnego procesu Continuous Integration.</span><br />
<span style="font-family: "arial";"><span style="font-family: "arial";"></span><br />
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><i>"I don't drink coffee, I take tea, my dear. I like my toast done on one side"</i></span></span><br />
<br />
<span style="font-family: "arial";">Hej hej! Mamy XXI wiek! Czas i w projektach bazodanowych się do niego zbliżyć!</span><br />
<br />
<span style="font-family: "arial";">Dziękuję za przeczytanie.</span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";"><b>p.s.</b> Przykłady? Pics or didn't happen? Stay tuned. Więcej pojawi się w kolejnych wpisach.</span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";"><b>p.s.2</b> garść linków do mądrzejszych ludzi:</span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";"><a href="http://www.codeproject.com/Articles/462206/Introduction-to-SSDT-SQL-Server-Data-Tools" target="_blank">http://www.codeproject.com/Articles/462206/Introduction-to-SSDT-SQL-Server-Data-Tools</a></span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";"><a href="http://devproconnections.com/database-development/get-know-sql-server-2012s-sql-server-data-tools" target="_blank">http://devproconnections.com/database-development/get-know-sql-server-2012s-sql-server-data-tools</a></span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";"><a href="http://www.codeproject.com/Articles/357905/Evaluating-SQL-Server-Data-Tools">http://www.codeproject.com/Articles/357905/Evaluating-SQL-Server-Data-Tools</a></span><br />
<span style="font-family: "arial";"></span><br />
<span style="font-family: "arial";"><a href="http://www.mssqltips.com/sqlservertip/2804/introduction-to-sql-server-data-tools/">http://www.mssqltips.com/sqlservertip/2804/introduction-to-sql-server-data-tools/</a></span></div>
</div>
Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com1tag:blogger.com,1999:blog-8979460837090429655.post-43320103916919924472015-02-17T17:23:00.002+01:002015-02-18T00:09:58.617+01:00SQLowa ciekawostka #1 - Uważaj na Exists kolego<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;">Tym razem, po serii nostalgiczno-branżowo-przemyśleniowych wpisów, będzie krótko i technicznie. Chciałbym się przed wami popisać swoją niewiedzą. Nie ma się w zasadzie czym chwalić, ale uważam, że głupotą nie jest brak wiedzy, co raczej wstyd przed jego okazaniem... No ale nie o to, nie o to, Oskarze, do sedna, do sedna...</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br /></div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;">Wczoraj podczas godzin spędzonych na szukaniu błędu natrafiłem w pewnej procedurze na takowy kod:</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br /></div>
<div style="text-align: justify;">
<pre class="brush: sql; " name="code" style="font-family: Verdana,sans-serif;">if exists (
select Kolumna
from Tabela t
where t.Id = @Id
)
begin
(...)zrób coś
end</pre>
</div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br /></div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;">Kod jak kod pomyślałem. Ale zastanowił mnie komentarz: "Zrób coś" tylko gdy Kolumna ma ustawioną wartość. Rzuciło mi się to w oczy bo z zasady jestem wyczulony na kod, który wymaga komentarzy. Okazało się, że mimo tego, że dla mojego rekordu Kolumna nie miała wartości to IF zawsze zwracał TRUE i "robił coś". Dlaczego?</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;"> </span></div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;">Ano dlatego, że dla EXISTS zwrócone przez subquery wartości nie mają żadnego znaczenia . Ważna dla niego jest tylko liczba zwróconych rekordów. Niezależnie od tego czy zwrócimy wszystkie czy jedną kolumnę, czy zwrócimy NULL, czy wartość dla Exists będzie to zawsze TRUE. Bo zwróciliśmy wiersz. </span></div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;"> </span></div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;">Pusty wiersz to nie to samo co brak wierszy.</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;"> </span></div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;">Brak decyzji też często bywa decyzją...</span><span style="font-family: Arial;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Dla zwizualizowania odpalcie sobie dwa zapytania:</span></div>
<div style="text-align: justify;">
<pre class="brush: sql; " name="code" style="font-family: Verdana,sans-serif;">SELECT 1 WHERE EXISTS(SELECT NULL)
</pre>
<span style="font-family: Arial, Helvetica, sans-serif;">i:</span> </div>
<pre class="brush: sql; " name="code" style="font-family: Verdana,sans-serif;">SELECT 1 WHERE EXISTS(SELECT NULL WHERE 1=2)
</pre>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span><br />
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;">Mała rzecz a cieszy. Niby podstawy podstaw, a człowiek może dać się złapać. A przecież na MSDN jest jak wół <a href="https://msdn.microsoft.com/en-us/library/ms188336.aspx" target="_blank">napisane</a>. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Codziennie człowiek uczy się czegoś nowego. I to chyba jest fajne w naszym zawodzie, czyż nie?</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br /></div>
</div>
Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-63705365897161283192015-01-31T21:03:00.001+01:002015-02-01T19:04:54.649+01:00Borys najlepiej dryblował<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Verdana,sans-serif;">Borys najlepiej dryblował, Cybor kręcił najlepsze rogale, było kilku kajtków, robiących 200 kapek. Moja piąta B, zawsze bo ciężkim meczu dokopywała piątej A. Od jakiegoś czasu graliśmy już tylko "na nowe". Ja nie robiłem setek zwodów, robienie kapek kończyłem na 20-30. Nie bawiło mnie to. Nie potrzebne mi były nadmiarowe ozdobniki, uważałem że koniec końców najważniejsze są podstawy. Kopnięcie piłki tam gdzie się chce. Co za różnica czy walnie się w okienko, brazylianę czy piłka ledwo się wtoczy? Ważne, żeby znalazła się w bramce. Koniec końców to się liczy. Sztuka dla sztuki? Nie dla mnie. </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">W Fifę nigdy nie wybierałem Brazylii, nawet w 98ym nie grałem Francją. To byłoby za proste. W końcu lepiej iść pod prąd. Co to za trudność grać na nastrojonej gitarze? Lepiej przegrywać z lepszymi niż wygrywać ze słabszymi. Lepiej być szeregowym graczem w Manchasterze Utd. niż kapitanem w Miedzi Legnica. </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Zawsze czytam instrukcje. W końcu trzeba się przygotować. Trzeba skręcić jak należy. </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Nie kupuję rzeczy pierwszych z brzegu, sprawdzam Ceneo, czytam fora, na Allegro ustawiam snajpera.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Wczoraj po dwóch latach naprawiłem zepsutą żaluzję.
</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span>
<span style="font-family: Verdana,sans-serif;">- Jaka jest Pana największa wada?</span><br />
<span style="font-family: Verdana,sans-serif;">- Jestem perfekcjonistą.
</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span>
<span style="font-family: Verdana,sans-serif;">Czasem mówię o sobie mistrz niedokończonych pomysłów. Jak większość z nas marzę o swoim własnym pomyśle, swoim własnym produkcie, startupie. Regularnie przystępuję do kolejnych błyskotliwych (w zamierzeniu) pomysłów i regularnie je nie dokańczam. Każda próba kończy się tak samo, <a href="https://www.youtube.com/watch?v=e3AtZnyXKIo" target="_blank">"to samo miejsce inna dziewczyna"</a>. </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Oczywiście każdy mój projekt musi mieć solidne fundamenty. Najpierw architektura, framework. Wszystko musi być na tip top, najnowsze rozwiązania, dobre praktyki, wzorce projektowe. W końcu mam teraz wolną rękę, nie muszę się przejmować marudzącym klientem. Ogólnie to chyba u nas w branży często bywa jak w PKP, wszystko by zajebiście szło gdyby nie klienci. Często naśmiewamy się z tego, że co on tam wie, że głupek, że nie będzie uczył ojca dzieci robić. Co tam kolorki, przycisk przesunięty o 3 pixele w lewo, albo nie ten odcień? Ważne żeby było SOLID. Najważniejsze to mieć dobrą architekturę i świetnie funkcjonujące trzewia. Nasze projekty są jak góra lodowa, olbrzymie pod spodem, tylko widocznych efektów jakoś tak niedużo. </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">W zeszłym tygodniu trafiła mi w ręce książka, w zasadzie ebook <a href="https://unicornfree.com/just-fucking-ship" target="_blank">"Just Fucking Ship"</a> napisana przez <a href="https://twitter.com/amyhoy" target="_blank">Amy Hoy</a>. Świetnie trafiła w mój nastrój zadumy nad tym co robię źle. Dlaczego Borys jest tym pamiętanym przez wszystkich piłkarzem z podwórka, nie ja? Dlaczego mój tato mówi, że mam słomiany zapał? Dlaczego Xamarin i SignalR świecą sukcesy, a mój niedokończony framework z podobnymi założeniami leży gdzieś na końcu mojego dysku nie rozwijany od kilku lat? Przecież wydawałoby się, że robię wszystko jak należy. Rozsądek. Solidne podstawy. Wiedza. Doświadczenie. Mr Prim and Proper. </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Może to właśnie dlatego, że popełniam te same błędy co wszyscy (no prawie wszyscy), czyli:
</span><br />
<span style="font-family: Verdana,sans-serif;">- nie skupiam się na złapaniu króliczka tylko go gonieniu. Projekt zaczynam od frameworka, stronę od layoutu, a w ogóle to od wymyślenia nazwy domeny. Przez co tracę okres największego entuzjazmu na pierdoły, które z punktu widzenia produktu są najmniej ważne.
</span><br />
<span style="font-family: Verdana,sans-serif;">- nie notuję, nie spisuję planów - "no bo po co? Nie potrzebuję tego - ćwiczę pamięć"
</span><br />
<span style="font-family: Verdana,sans-serif;">-
nie skupiam się na celu, nie wyznaczam sobie deadline'ów.</span><br />
<span style="font-family: Verdana,sans-serif;">- nie postępuję w myśl zasady "start small, grow big". </span><br />
<br />
<blockquote class="twitter-tweet" lang="en">
"How programmers spend time on a project. This one's funny because it's true"
via <a href="https://twitter.com/ErlangSolutions">@ErlangSolutions</a> <a href="http://t.co/qYJpPsQLFS">pic.twitter.com/qYJpPsQLFS</a><br />
— About Programming (@abt_programming) <a href="https://twitter.com/abt_programming/status/561488797440176128">January 31, 2015</a></blockquote>
<script async="" charset="utf-8" src="//platform.twitter.com/widgets.js"></script>
<span style="font-family: Verdana,sans-serif;"><br /></span>
<span style="font-family: Verdana,sans-serif;">Książka Amy nie jest wielce odkrywcza, nie da złotej recepty - nawet do tego nie aspiruje. To co na pewno da to powiew świeżości w głowie, otwarcie kilku zamkniętych zapadek i garść cennych, konkretnych, życiowych porad. Najważniejsza z nich to: <b>wyznacz sobie cel, termin i po prostu to kurwa zrób</b>. Najpierw cel i czas potem zakres i metody realizacji. Oczywiście, każdy z nas powie "e no, tak to się nie zawsze da zrobić". Tylko spójrzcie inaczej: czy chcąc zaprosić znajomych na obiad planujemy, że "może to za 2 tygodnie jednak, bo nie zdążę zrobić trzydaniowego obiadu, tortu i domowej nalewki". Przecież tak nie robimy. Dopasowujemy listę dań lub kupujemy coś gotowego. Czy nie da się tej polityki przenieść na grunt naszych też projektów? </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Amy zauważa, że za bardzo skupiamy się na projekcie jako całości. Nie wyznaczamy sobie małych celów, których zrealizowanie pozwoliłoby nam być osiągnąć satysfakcję i motywację do kolejnych działań. Tak bardzo skupiamy się na ogólnej wizji, że w końcu zarzucamy nasz pomysł nie robiąc niczego. Boimy się, że nie jest on wystarczająco fajny, wystarczająco innowacyjny. Czemu nie damy innym szansy tego ocenić? Zostajemy w progach startowych zamiast po prostu biec i zobaczyć gdzie dobiegniemy. Zapominamy, że aby wejść na piętro należy pokonać schody krok po kroku. Stojąc na parterze, zastanawiając czy damy radę wejść niczego nie osiągniemy. Możemy nawet wjechać windą, bylebyśmy to kurwa zrobili. </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Po tej lekturze nie wywrócę swojego życia do góry nogami, nie stanę się nagle innym człowiekiem. Po prostu tym razem spróbuję swoje plany wreszcie kurwa dowieźć. </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Tydzień temu, w wieku prawie 30 lat odebrałem swój pierwszy piłkarski medal. Jest jeszcze nadzieja.
</span></div>
Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com4tag:blogger.com,1999:blog-8979460837090429655.post-90587278198584700522014-06-10T20:48:00.001+02:002014-06-11T20:27:56.693+02:00Na temat branży<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Verdana,sans-serif;">Naszym programistycznym światkiem wstrząsnął ten oto wpis: <a href="http://natemat.pl/105597,it-arystokracja">http://natemat.pl/105597,it-arystokracja</a>. Artykuł jak artykuł, nieco grafomański, nieco tendencyjny, ale w gruncie rzeczy nic wielkiego. Klasyczny przedstawiciel domorosłego blogowego "dziennikarstwa". Gdy sam na niego trafiłem to zapomniałem o nim gdzieś pomiędzy jednym, a drugim mrugnięciem okiem. Wydawało mi się, że to nic nowego, rzeczy ogólnie znane, ale wszedłem na "fejsa", a tam gorączka. Wpisy u znajomych, nawet na <a href="https://www.facebook.com/groups/net.developers.poland/permalink/293254287522600/" target="_blank">Grupie .NET szaleństwo</a>. Truizm "uderz w stół, a nożyczki się odezwą" stał się ciałem. O tempora, o mores!</span><br />
<span style="font-family: Verdana,sans-serif;">Kto by przypuszczał, że taki wpis wzbudzi</span><span style="font-family: Verdana,sans-serif;"><span style="font-family: Verdana,sans-serif;"> tyle</span> emocji... Aż sam się zagotowałem (tak, Johann to sem ja). Ale to co wzbudziło we mnie tyle emocji to niechęć do zwykłego powiedzenia "no okej, mam lepiej niż inni i co Ci do tego?". Czytając wpisy, rozmawiając ze znajomymi dowiedziałem się, że na zachodzie to Panie eurasy kokosy, a u nas co, ziemniaki mają być? Jak nie będę pracował za dziesięć tysi to co? Mam za miskę ryżu pracować? A w ogóle to po co ta dyskusja, prawa rynku, podaż, popyt. Panowie w prążki mający pieniążki na mnie zarabiają to ja mam nic nie przytulić? Frajer przeca nie jestem! Zgłupiałeś tak jak Ci co wybrali inne studia niż programistyczne? Życie to w ogóle brutalna dżungla, nie chcesz to jedź jak prezes Optimusa w Bieszczady i hoduj owce. No i ogólnie ten tego...</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://img3.wikia.nocookie.net/__cb20070507234714/uncyclopedia/images/b/be/Shitstorm-flyer.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://img3.wikia.nocookie.net/__cb20070507234714/uncyclopedia/images/b/be/Shitstorm-flyer.jpg" height="240" width="320" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span>
<span style="font-family: Verdana,sans-serif;">No dobra troszeczkę wyolbrzymiam, ale tak jak pisałem na fejsowej gównoburzy - <span data-ft="{"tn":"K"}" data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body"><span class="UFICommentBody" data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0"><span data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0.0"><span data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0.0.$end:0:$0:0">nie rozumiem obruszenia, ż</span></span><span data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0.3"><span data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0.3.0"><span data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0.3.0.$end:0:$0:0">e ktoś nazwał naszą grupę uprzywilejowaną, bo przecież tacy jesteśmy. Popyt nas takimi uczynił, nie my sami.</span></span></span></span></span></span><br />
<span style="font-family: Verdana,sans-serif;"><span data-ft="{"tn":"K"}" data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body"><span class="UFICommentBody" data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0"><span data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0.3"><span data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0.3.0"><span data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0.3.0.$end:0:$0:0">
Trochę dziecinne jest wg mnie udawać, że jest inaczej i się obrażać na
takie stwierdzenia. Dodatkowo nie rozumiem takiego podejścia, że mnie
się udało, inni mogli robić to co ja to też by tak mieli. Chodzi mi
tylko o odrobinę więcej pokory i szacunku dla innych. </span></span></span></span></span></span><br />
<span style="font-family: Verdana,sans-serif;"><span data-ft="{"tn":"K"}" data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body"><span class="UFICommentBody" data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0"><span data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0.3"><span data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0.3.0"><span data-reactid=".hy.1:3:1:$comment293254287522600_293426217505407:0.0.$right.0.$left.0.0.1:$comment-body.0.3.0.$end:0:$0:0">Tego sobie i innym
życzę ;)</span></span></span></span></span></span></div>
Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com7tag:blogger.com,1999:blog-8979460837090429655.post-36962154936906462702014-05-31T14:13:00.004+02:002014-05-31T14:50:38.053+02:00Refleksyjnie plus pierwszy w historii Vlog - Podstawy programowania w Office 2013<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Verdana,sans-serif;">Heh. </span><br />
<span style="font-family: Verdana,sans-serif;">To już ponad 1,5 roku od poprzedniego wpisu. </span><br />
<span style="font-family: Verdana,sans-serif;">Gdzieś w między czasie uleciał trochu wolny czas, trochu zapał. Tak to już jest. Jutro się tym zajmę, może w następnym tygodniu, w weekend na pewno będę miał czas, a jak nie to już od następnego miesiąca będę królem samozaparcia i samorealizacji. Każdy to zna, każdy to przeżywa. Potem się okazuje, że to święte oburzenie zostało zamienione na czas spędzony na poobiednich drzemkach, oglądaniu 9 sezonów Dwóch i pół, czy graniu w 2048. Potem to już tylko, że jestem zarobiony, w pracy ciężko i w ogóle tyle roboty, że taczki nie ma jak załadować, a o szyby deszcz dzwoni, deszcz dzwoni jesienny. </span><br />
<span style="font-family: Verdana,sans-serif;">Jakiś czas temu "popełniłem wykon" (tak bardzo nie cierpię nowomowy, że aż musiałem jej użyć) na potrzeby wewnętrznych szkoleń w firmie, w której pracuję. Programowanie w Office 2013. Temat wydaje mi się, że ciekawy i mało zagospodarowany. Przez co duże w nim pole do popisu. Z racji, że to mój debiut w tej materii to proszę o litościwość.</span><br />
<br /></div>
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/UIOhfYkg9BA?list=UUCKUNfHOrBzIiJrCgI5AvxQ" width="560"></iframe>
<br />
<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-family: Verdana,sans-serif;">Mam nadzieję, że dorównałem mistrzowi:</span></div>
<br /></div>
<iframe width="560" height="315" src="//www.youtube.com/embed/FNWnfM8Ney4" frameborder="0" allowfullscreen></iframe>
<div dir="ltr" style="text-align: left;" trbidi="on"><br />
<span style="font-family: Verdana, sans-serif;">Dla chętnych - źródła: <a href="http://www.mediafire.com/download/ogkc222buvj5aud/OfficeJiraApp.zip" target="_blank">pobierz</a></span></div>
Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-82019736333354793272012-11-08T09:53:00.002+01:002012-11-08T09:53:57.932+01:00Prezent od Microsoft - Darmowa książka o programowaniu w Windows 8<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Verdana, sans-serif;">Microsoft konsekwentnie kontynuuje taktykę ściągania nie .NETowych programistów - udostępnił darmową książkę w ramach Microsoft Press: "Programming Windows 8 Apps with HTML, CSS, and JavaScript". Jest ona dostępna pod adresem:</span><br />
<span style="font-family: Verdana, sans-serif;">- <a href="http://blogs.msdn.com/b/microsoft_press/archive/2012/10/29/free-ebook-programming-windows-8-apps-with-html-css-and-javascript.aspx" target="_blank">http://blogs.msdn.com/b/microsoft_press/archive/2012/10/29/free-ebook-programming-windows-8-apps-with-html-css-and-javascript.aspx</a></span><br />
<span style="font-family: Verdana, sans-serif;">Nie do końca jestem przekonany do tego, że HTML5, JavaScript i CSS jest tym kierunkiem, w którym powinny podążać systemy operacyjne. Wg mnie te technologie są chaotyczne, mają pełno złych zaszłości historycznych i są ciężkie w utrzymaniu. (Nie)stety nie tylko Microsoft podąża w tą stronę - Apple, Google również mocno w nią idą. </span><br />
<span style="font-family: Verdana, sans-serif;">A wy co o tym wszystkim sądzicie? </span><span style="font-family: Verdana, sans-serif;"><br /></span></div>
Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-47307716114947050302012-10-30T17:54:00.000+01:002012-10-30T17:55:42.389+01:00Serializacja dla .NET 4.5 oraz Windows Runtime przy pomocy Sharpserializer <div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Verdana, sans-serif;">Trochę mnie nie było, dawno już nie pisałem - ten post będzie dla mnie nietypowy - krótki. Mam nadzieję, że to będzie jego zaleta.</span><br />
<span style="font-family: Verdana, sans-serif;">W swoim projekcie-po-godzinach do serializacji danych używam biblioteki <a href="http://www.sharpserializer.com/en/index.html" target="_blank">SharpSerializer</a>. Projekt ma środowiska klienckie napisane w Silverlight i Windows Phone. Nie ma w nich klasy BinaryFormatter przez co bez stosowania zewnętrznych bibliotek trzeba by stosować sztuczki z serializacją poprzez mechanizm DataContract z WCF (więcej szczegółów <a href="http://www.damonpayne.com/post/2010/05/24/DataContract-based-Binary-Serialization-for-Silverlight.aspx" target="_blank">na blogu Damona Payne'a</a>). Nie jest to zbyt wygodne wg mnie.</span><br />
<span style="font-family: Verdana, sans-serif;">SharpSerializer pozwala w prosty, wygodny i efektywny sposób serializować dane do postaci binarnej. </span><br />
<span style="font-family: Verdana, sans-serif;">Dlaczego tak nagle o tym piszę? W tym tygodniu zacząłem przenosić kod projektu na .NET 4.5 i Windows Runtime. Niestety nie zostały do tej pory wypuszczone wersje na te środowiska.</span><br />
<span style="font-family: Verdana, sans-serif;">Na szczęście ze strony można ściągnąć kody źródłowe.</span><br />
<span style="font-family: Verdana, sans-serif;">Pobrałem je, przekonwertowałem, poprawiłem część rzeczy, przekompilowałem i okazało się, że wszystko wygląda jakby działało.</span><br />
<span style="font-family: Verdana, sans-serif;">Efekt moich prac możecie pobrać: <a href="http://joomanji.no-ip.org/blog/sharpSerializer.zip" target="_blank">tutaj (src + dll)</a>.</span><br />
<span style="font-family: Verdana, sans-serif;">Więcej informacji na temat SharpSerializer pod linkami:</span><br />
<span style="font-family: Verdana, sans-serif;">- <a href="http://www.sharpserializer.com/en/tutorial/index.html">http://www.sharpserializer.com/en/tutorial/index.html</a></span><br />
<span style="font-family: Verdana, sans-serif;">- <a href="http://www.codeproject.com/Articles/76530/XML-Serialization-of-Generic-Dictionary-Multidimen">http://www.codeproject.com/Articles/76530/XML-Serialization-of-Generic-Dictionary-Multidimen</a></span><br />
<span style="font-family: Verdana, sans-serif;">- <a href="http://www.codeproject.com/Articles/240621/How-to-serialize-data-effectively-Custom-serializa">http://www.codeproject.com/Articles/240621/How-to-serialize-data-effectively-Custom-serializa</a></span><br />
<span style="font-family: Verdana, sans-serif;">- <a href="http://www.codeproject.com/Articles/116020/Binary-Serialization-to-Isolated-Storage-in-Silver">http://www.codeproject.com/Articles/116020/Binary-Serialization-to-Isolated-Storage-in-Silver</a></span><br />
<span style="font-family: Verdana, sans-serif;">Zachęcam do zabawy z SharpSerializerem, naprawdę dobra biblioteka.</span></div>
Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-59388453925355717302012-04-15T17:04:00.001+02:002012-04-15T17:07:51.479+02:00Jak z kilku dllek zrobić jedną, czyli modularność przy pomocy ILMerge<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;"><b>Wstęp</b></span> </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Pracuję aktualnie nad strukturą pewnego projektu. Ideą, która przyświeca przy jej tworzeniu jest to, żeby była jak najbardziej modularna - tak by składała się z niezależnych, niepowiązanych ze sobą podaplikacji. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Aby lepiej przybliżyć problem przyjrzyjmy się przykładowi:</span></div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-X4RYdWKZWXY/T4qHlUkQsWI/AAAAAAAAAUU/SvZiH9JRN6Y/s1600/01.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="275" src="http://4.bp.blogspot.com/-X4RYdWKZWXY/T4qHlUkQsWI/AAAAAAAAAUU/SvZiH9JRN6Y/s400/01.png" width="400" /></a></td></tr>
<tr style="font-family: Verdana,sans-serif;"><td class="tr-caption" style="text-align: center;"><b>Rysunek 1 - Przykładowa struktura</b></td></tr>
</tbody></table>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Przyjmijmy, że chcemy stworzyć moduł zarządzania użytkownikami, który będziemy używać w kilku tworzonych przez nas aplikacjach. Nie chcemy, bowiem za każdym razem wynajdywać koła od początku. Moduł ten składać się będzie z podmodułów odpowiadających za rejestrację, logowanie, uprawnienia. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Standardowo do każdego z tych "klocków" utworzylibyśmy osobny projekt, chcąc dodać do naszych aplikacji musielibyśmy wrzucić 4 osobne dllki:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- główną - Modułu Zarządzania Użytkownikami</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- 3 zależne - Moduł Rejestracji, Moduł Logowania, Moduł Uprawnień</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Dorzucenie 4 dllek nie wydaje się chyba wielkim problemem, prawda? </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Pójdźmy jednak dalej. Załóżmy, że nasza firma zajmuje się tworzeniem stron internetowych. Mamy kilka "żyjących" i rozwijanych stron. Każdą z nich zajmuje się osobny zespół programistów, mamy również dział geeków, którzy zajmuje się core'em. Nasi klienci stwierdzili, że chcieliby mieć możliwość logowania się i rejestracji przy pomocy otwartych systemów uwierzytelniania jak OpenID, Google, Facebook. Zespół naszych geeków czym prędzej zaczyna się tym zajmować i na koniec generuje następującą strukturę:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-UTgOq2bW8dQ/T4qNak6bLwI/AAAAAAAAAUc/yqJc_1EIxBM/s1600/02.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="308" src="http://4.bp.blogspot.com/-UTgOq2bW8dQ/T4qNak6bLwI/AAAAAAAAAUc/yqJc_1EIxBM/s400/02.png" width="400" /></a></td></tr>
<tr style="font-family: Verdana,sans-serif;"><td class="tr-caption" style="text-align: center;"><b>Rysunek 2 - Rozszerzona struktura</b></td></tr>
</tbody></table>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Przy uaktualnianiu Modułu Zarządzania Użytkownikami musimy pamiętać, że musimy dodać kolejne dziewięć dllek dla każdego z podmodułów. W sumie mamy trzynaście dllek, może i pechowa liczba, ale to dalej nie jest krytyczny problem, czyż nie? Krytycznie jednak zaczyna się robić, gdy mamy kilka używanych w wielu miejscach modułów, z których każdy składa się z podmodułów. Gdy jeszcze trzymamy się zasadom luźno powiązanych klas, inversion of control i korzystamy z kontenerów dependency injection to sytuacja robi się jeszcze bardziej problematyczna, a zapomnienie dorzucenia dllki łatwiejsze i bardziej problematyczne.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Dużym uproszczeniem byłaby sytuacja gdy każdy moduł jest osobną dllką. Dzięki temu programiści, którzy z niego korzystają nie muszą się zastanawiać z czego on dokładnie się składa, musiał by tylko wiedzieć jak się go używa. </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">Co to jest ILMerge?</span></b></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">ILMerge jest narzędziem dostarczonym przez Microsoft, pozwalającym na łączenie kilku asemblatów w jeden (stąd jego nazwa - łączenie <a href="http://pl.wikipedia.org/wiki/Common_Intermediate_Language" target="_blank">ILa</a>). Radzi on sobie bez większych problemów również z łączeniem plików .pdb umożliwiając tym samym debugowanie. Dostarczany jest w postaci pliku EXE (można go pobrać pod <a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=17630" target="_blank">linkiem</a>), który uruchomiony z odpowiednimi parametrami pozwala nam na złączenie asemblatów. Przykładowe jego wywołanie to:</span></div>
<div style="text-align: justify;">
<br /></div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">ilmerge /target:winexe /out:myprogram.exe yourexe.exe yourlibrary.dll
</pre>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Gdzie:</span><br />
<span style="font-family: Verdana,sans-serif;">- <b>ilmerge </b>- nazwa pliku ilmerge'a </span><br />
<span style="font-family: Verdana,sans-serif;">- <b>/target</b> - parametr mówiący czy nasz asemblat ma być plikiem exe (</span><span style="font-family: Verdana,sans-serif;"><b>winexe</b>) cz dllką (<b>module</b>) </span><br />
<span style="font-family: Verdana,sans-serif;">- <b>/out:</b> - parametr mówiący o nazwie wynikowego pliku, podajemy też asemblaty, które chcemy złączyć</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Jak to zobaczyłem to stwierdziłem, że bardzo to fajne, tylko że wywoływanie za każdym razem polecenia z linii komend. Na szczęście znalazłem świetny <a href="http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx" target="_blank">artykuł</a> Scotta Hanselmana jak można ten proces zautomatyzować.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">Automatyczne wywołanie ILMerge</span></b></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">MSBuild pozwala na zdefiniowanie akcji, które będą wykonywane po procesie zbudowania projektu (tzw. Post build actions). Możemy zatem zdefiniować akcję, która będzie polegała na wywołaniu ILMerge'a z odpowiednimi parametrami dla wybranych przez nas projektów. Jak tego dokonać? Ponieważ pliki projektów są zarazem plikami MSBuilda możemy je odpowiednio zmodyfikować.</span><br />
<span style="font-family: Verdana,sans-serif;">Zacznijmy od utworzenia nowej solucji i struktury projektów. Niech wygląda ona następująco:</span><br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-jB0lQJkxnSA/T4qxBPqNl9I/AAAAAAAAAUk/t_ZzIxA8Rz8/s1600/03.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="http://1.bp.blogspot.com/-jB0lQJkxnSA/T4qxBPqNl9I/AAAAAAAAAUk/t_ZzIxA8Rz8/s400/03.png" width="353" /></a></td></tr>
<tr style="font-family: Verdana,sans-serif;"><td class="tr-caption" style="text-align: center;"><b>Rysunek 3 - przykładowa struktura projektów</b></td></tr>
</tbody></table>
<br />
<span style="font-family: Verdana,sans-serif;">Odpowiada ona przykładowej strukturze projektów przedstawionej wcześniej. Mamy projekt ILMergeSample.UserManagementModule, który ma referencję do trzech podmodułów. Zbudujmy teraz nasz solucję i przejdźmy do katalogu Debug dla naszego projektu modułu obsługi pracowników.</span><br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/--oxM4kod9Gs/T4qyf0CyriI/AAAAAAAAAU0/vXGzBHUof-U/s1600/04.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="212" src="http://3.bp.blogspot.com/--oxM4kod9Gs/T4qyf0CyriI/AAAAAAAAAU0/vXGzBHUof-U/s400/04.png" width="400" /></a></td></tr>
<tr style="font-family: Verdana,sans-serif;"><td class="tr-caption" style="text-align: center;"><b>Rysunek 4 - Wynik standardowego builda</b></td></tr>
</tbody></table>
<br />
<span style="font-family: Verdana,sans-serif;">Zgodnie z przewidywaniami standardowo skopiował dllki podmodułów. Przejdźmy więc do sedna artyukułu i zacznijmy łączyć je w jedną. Rozpocznijmy od skopiowania pliku ILMerge.exe </span><span style="font-family: Verdana,sans-serif;">do struktury naszej solucji </span><span style="font-family: Verdana,sans-serif;">(domyślnie znajduje się w "C:\Program Files (x86)\Microsoft\ILMerge")</span><span style="font-family: Verdana,sans-serif;">. Pozwoli nam to uniezależnić od tego czy inny developer ma go na swoim komputerze i pod jaką ścieżką się u niego znajduje.</span><br />
<span style="font-family: Verdana,sans-serif;">Dodajmy również plik o nazwie "Ilmerge.CSharp.targets".</span><br />
<span style="font-family: Verdana,sans-serif;">Nasza struktura solucji powinna wyglądać teraz następująco:</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-KLAseZw35Gk/T4q2TA1KLUI/AAAAAAAAAU8/Hoi3w3-CPmE/s1600/05.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="271" src="http://4.bp.blogspot.com/-KLAseZw35Gk/T4q2TA1KLUI/AAAAAAAAAU8/Hoi3w3-CPmE/s400/05.png" width="400" /></a></td></tr>
<tr style="font-family: Verdana,sans-serif;"><td class="tr-caption" style="text-align: center;"><b>Rysunek 5 - Struktura projektu po dodaniu ILMerge'a</b></td></tr>
</tbody></table>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Otwórzmy teraz plik </span><span style="font-family: Verdana,sans-serif;">"Ilmerge.CSharp.targets" i wklejmy do niego następujące dane:</span><br />
<pre class="brush: xml; " name="code" style="font-family: Verdana,sans-serif;"><Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Target Name="AfterBuild">
<CreateItem Include="@(ReferencePath)" Condition="'%(CopyLocal)'=='true' and '%(ReferencePath.IlMerge)'=='true'">
<output >="" <="" createitem="" itemname="IlmergeAssemblies" taskparameter="Include">
<Message Text="MERGING: @(IlmergeAssemblies->'%(Filename)')" Importance="High" />
<Exec Command="&quot;$(SolutionDir)\Ilmerge.exe&quot;
/targetplatform:v4,&quot;%ProgramFiles%\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0&quot;
/out:@(MainAssembly) &quot;@(IntermediateAssembly)&quot; @(IlmergeAssemblies->'&quot;%(FullPath)&quot;', ' ')" />
</Target>
<Target Name="_CopyFilesMarkedCopyLocal"/>
</Project>
</output></pre>
<br />
<span style="font-family: Verdana,sans-serif;">Co to tak naprawdę robi? Prześledźmy to po kolei:</span><br />
<span style="font-family: Verdana,sans-serif;">- <b>Project DefaultTargets="Build"</b> - określamy tutaj, że definiujemy akcję dla builda</span><br />
<span style="font-family: Verdana,sans-serif;">- <b>Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets"</b> - importujemy tutaj domyślne ustawienia builda, nie chcemy bowiem wszystko definiować od początku, tylko nadpisać część ustawień</span><br />
<span style="font-family: Verdana,sans-serif;">- <b>CreateItem Include="@(ReferencePath)" Condition="'%(CopyLocal)'=='true' and '%(ReferencePath.IlMerge)'=='true'"</b> - dzięki temu warunkowi wybieramy do złączenia te asemblaty, które są dołączone do naszego projektu i mają zaznaczoną opcję "Copy Local" oraz "ILMerge" na true</span><br />
<span style="font-family: Verdana,sans-serif;">- <b>Message Text</b> - tutaj definiujemy wiadomość, która będzie informowała nas w outputcie o tym, że dokonujemy złączenia asemblatów w trakcie budowania projektu</span><br />
<span style="font-family: Verdana,sans-serif;">- <b>Exec Command</b> - tutaj definiujemy odpowiednie wywołanie ILMerge'a. Moja konfiguracja jest specyficzna dla .NET 4.0, jeżeli macie asemblaty w innej wersji .NET powinniście zmodyfikować parametr /targetplatform</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Mając konfigurację MSBuilda z ILMerge powinniśmy jeszcze poinformować nasz projekt, że ma z niej korzystać. Dokonujemy tego poprzez ręczną modyfikację pliku projektu (naciskamy na niego prawym przyciskiem i wybieramy opcję "Edit Project File").</span><br />
<span style="font-family: Verdana,sans-serif;">Po otworzeniu pliku projektu naszego Modułu Zarządzania Użytkownikami powinniśmy odnaleźć następujące linijki:</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-uAOXuOKV-gE/T4q-LblOPZI/AAAAAAAAAVE/U3xUElNgY84/s1600/06.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="117" src="http://3.bp.blogspot.com/-uAOXuOKV-gE/T4q-LblOPZI/AAAAAAAAAVE/U3xUElNgY84/s400/06.png" width="400" /></a></td></tr>
<tr style="font-family: Verdana,sans-serif;"><td class="tr-caption" style="text-align: center;"><b>Rysunek 6 - Plik projektu przed modyfikacjami</b></td></tr>
</tbody></table>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Jedyne co musimy zrobić to zmodyfikować plik następująco:</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-1i3D_tq4hsk/T4rCSMi6pZI/AAAAAAAAAVM/cMYdo-jOYSk/s1600/07.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="193" src="http://1.bp.blogspot.com/-1i3D_tq4hsk/T4rCSMi6pZI/AAAAAAAAAVM/cMYdo-jOYSk/s400/07.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><b style="font-family: Verdana,sans-serif;">Rysunek 7 - Plik projektu po modyfikacjach</b></td></tr>
</tbody></table>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Dodaliśmy tylko dla wybranych przez nas projektów zmienną <IlMerger> z wartością true informując o tym, że chcemy, żeby projekt został połączony i podmieniliśmy domyślną konfigurację builda przygotowaną wcześniej w pliku "Ilmerge.CSharp.targets".</span><br />
<span style="font-family: Verdana,sans-serif;"><br />Zapiszmy teraz plik projektu, przeładujmy go i przebudujmy. Ponownie zerknijmy do katalogu Debug naszego Modułu Zarządzania Użytkownikami</span><span style="font-family: Verdana,sans-serif;"> i ujrzymy, że została wygenerowana tylko jedna dllka.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-X6ls1r4ROsw/T4rPTdee2QI/AAAAAAAAAVU/QgQlJnHDLbg/s1600/08.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="157" src="http://3.bp.blogspot.com/-X6ls1r4ROsw/T4rPTdee2QI/AAAAAAAAAVU/QgQlJnHDLbg/s400/08.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><b style="font-family: Verdana,sans-serif;">Rysynek 8 - Wygenerowane pliki po konfiguracji ILMerge</b></td></tr>
</tbody></table>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">Czy ILMerge działa dla Silverlighta i Phone'a?</span></b></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Ależ owsze, czemu nie. Należy tylko odpowiednio spreparować nasz plik targets: </span><br />
<span style="font-family: Verdana,sans-serif;">- dla Phone'a nasz plik wyglądał by następująco: </span><br />
<pre class="brush: xml; " name="code" style="font-family: Verdana,sans-serif;"><Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
<Target Name="AfterBuild">
<CreateItem Include="@(ReferencePath)" Condition="'%(CopyLocal)'=='true' and '%(ReferencePath.IlMerge)'=='true'">
<output>
<Message Text="MERGING: @(IlmergeAssemblies->'%(Filename)')" Importance="High" />
<Exec Command="&quot;$(SolutionDir)\Ilmerge.exe&quot;
/targetplatform:v4,&quot;%ProgramFiles%\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone&quot;
/out:@(MainAssembly) &quot;@(IntermediateAssembly)&quot; @(IlmergeAssemblies->'&quot;%(FullPath)&quot;', ' ')" />
</Target>
<Target Name="_CopyFilesMarkedCopyLocal"/>
</Project>
</output></pre>
<span style="font-family: Verdana,sans-serif;">- dla Silverlight'a nasz plik wyglądał by następująco: </span><br />
<pre class="brush: xml; " name="code" style="font-family: Verdana,sans-serif;"><Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
<Target Name="AfterBuild">
<CreateItem Include="@(ReferencePath)" Condition="'%(CopyLocal)'=='true' and '%(ReferencePath.IlMerge)'=='true'">
<output>
<Message Text="MERGING: @(IlmergeAssemblies->'%(Filename)')" Importance="High" />
<Exec Command="&quot;$(SolutionDir)\Ilmerge.exe&quot;
/targetplatform:v4,&quot;%ProgramFiles%\Reference Assemblies\Microsoft\Framework\Silverlight\v5.0&quot;
/out:@(MainAssembly) &quot;@(IntermediateAssembly)&quot; @(IlmergeAssemblies->'&quot;%(FullPath)&quot;', ' ')" />
</Target>
<Target Name="_CopyFilesMarkedCopyLocal"/>
</Project>
</output></pre>
<br />
<span style="font-family: Verdana,sans-serif;">Jak łatwo zauważyć podmieniliśmy tylko ścieżki do plików z domyślnymi ustawieniami buildów dla tych środowisk oraz poprawiliśmy wywołanie ILMerge'a w Exec Command tak aby dotyczyła właściwej platformy.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">ILMerge i Resharper</span></b></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Jeżeli zrobiliście wszystko zgodnie z powyższym opisem to po dodaniu klas i próbie wywołania ich w projekcie Application okaże się, że Resharper nie widzi klas z podmodułów (Authorization, Registration, Login). Dzieje się tak dlatego, że projekty naszych modułów znajdują się w tej samej solucji co projekt Application. Jeżeli utworzylibyśmy osobną solucję, w której nie znajdowałyby się nasze podmoduły, a tylko projekt Application okaże się, że Resharper widzi je już bez większych problemów.</span><br />
<span style="font-family: Verdana,sans-serif;">Jest to błąd Resharpera - chociaż oni <a href="http://devnet.jetbrains.net/message/5253869#5253869" target="_blank">twierdzą </a>inaczej. Zapewne nie chce im się tego naprawiać, ale oczywiście mają na to mądre wytłumaczenie. Mówią, że jeżeli doprowadziło się do takiej sytuacji to znaczy, że układ projektów jest zły. Można by się było z nimi po części zgodzić, bo moduły powinny być traktowane jako całość i posiadać osobne solucje a nie być wepchnięte w jedną dużą. Jest to jednak spore uniedogodnienie, szczególnie na początku tworzenia systemu, gdy moduły są często zmieniane - trzeba wtedy pracować na kilku solucjach na raz, albo ignorować błędnie podświetlony przez Resharpera kod.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">Podsumowanie i linki</span></b></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Mam nadzieję, że tym artykułem udało mi się przybliżyć to jak ILMerge może pomóc nam przy tworzeniu modularnych aplikacji oraz przede wszystkim ułatwić życie programistom.</span><br />
<span style="font-family: Verdana,sans-serif;">Kody źródłowe przykładów z tego artykułu możecie znaleźć <a href="http://joomanji.no-ip.org/blog/ILMergeSample.rar" target="_blank">tutaj</a>.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Linki do artykułów z których korzystałem przy tworzeniu tego wpisu to:</span><br />
<span style="font-family: Verdana,sans-serif;">- <a href="http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx">http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx</a></span><br />
<span style="font-family: Verdana,sans-serif;">- <a href="http://blogs.msdn.com/b/jomo_fisher/archive/2006/03/05/544144.aspx">http://blogs.msdn.com/b/jomo_fisher/archive/2006/03/05/544144.aspx</a></span><br />
<span style="font-family: Verdana,sans-serif;">- <a href="http://blogs.clariusconsulting.net/kzu/leveraging-ilmerge-to-simplify-deployment-and-your-users-experience/">http://blogs.clariusconsulting.net/kzu/leveraging-ilmerge-to-simplify-deployment-and-your-users-experience/</a></span><br />
<span style="font-family: Verdana,sans-serif;">- <a href="http://awkwardcoder.blogspot.com/2011/05/using-ilmerge-for-windows-phone-7.html">http://awkwardcoder.blogspot.com/2011/05/using-ilmerge-for-windows-phone-7.html</a></span><br />
<span style="font-family: Verdana,sans-serif;">- <a href="http://albao.wordpress.com/tag/ilmerge-error-documentation-exception-net/">http://albao.wordpress.com/tag/ilmerge-error-documentation-exception-net/</a></span><br />
<span style="font-family: Verdana,sans-serif;">- <a href="http://nitoprograms.blogspot.com/2010/09/using-ilmerge-with-net-40-andor-rx.html">http://nitoprograms.blogspot.com/2010/09/using-ilmerge-with-net-40-andor-rx.html</a></span><br />
<span style="font-family: Verdana,sans-serif;">- <a href="http://devnet.jetbrains.net/message/5253869#5253869">http://devnet.jetbrains.net/message/5253869#5253869</a></span></div>
</div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com2tag:blogger.com,1999:blog-8979460837090429655.post-23908512823046949362012-03-23T09:35:00.001+01:002012-03-23T15:14:40.547+01:00WrocNet - Team Foundation Server to nie SVN - Materiały<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Przedwczoraj (środa 21.03) debiutowałem w roli "wykładowcy" na spotkaniu Wrocławskiej grupy .NET. Zaprezentowałem tam rozwinięcie moich wpisów związanych z połączeniem SCRUM z Team Foundation Server. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Mnie jako prezentującemu na pewno podobało się zaangażowanie słuchaczy, za co serdecznie dziękuję. Nie wiem jak było w drugą stronę, jeżeli ktoś był i chce się podzielić swoimi wrażeniami (nawet najbardziej negatywnymi) to bardzo proszę o komentarze.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Obiecałem, że przedstawię materiały, z których dociekliwi mogliby się dowiedzieć więcej o przedstawianym przeze mnie temacie.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Jako pierwsze zareklamuje swoje wcześniejsze wpisy:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://oskar-at-net.blogspot.com/2011/11/scrum-i-team-foundation-system-cz1.html" target="_blank">Opis metodyki SCRUM</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://oskar-at-net.blogspot.com/2011/11/scrum-i-team-foundation-server-cz2.html" target="_blank">Instalacja TFS 11</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://oskar-at-net.blogspot.com/2011/11/scrum-i-team-foundation-server-cz3.html" target="_blank">Wystawienie TFS na zewnątrz</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://oskar-at-net.blogspot.com/2011/11/scrum-i-team-foundation-server-cz4.html" target="_blank">Utworzenie projektu w TFS</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://oskar-at-net.blogspot.com/2011/11/scrum-i-team-foundation-server-cz5.html" target="_blank">Continuous Integration i automatyczne buildy</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://oskar-at-net.blogspot.com/2011/12/scrum-i-team-foundation-server-cz6.html" target="_blank">Proces TDD w realizowanym projekcie</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">A teraz linki z których korzystałem:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://blogs.msdn.com/b/visualstudioalm/archive/2011/09/20/visual-studio-team-foundation-server-11-developer-preview-what-s-new-for-team-foundation-server.aspx" target="_blank">Ogólny opis nowości w TFS 11</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://msdn.microsoft.com/en-us/library/hh409276%28v=vs.110%29.aspx" target="_blank">Tworzenie storyboardów</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://msdn.microsoft.com/en-us/library/hh301770%28v=vs.110%29.aspx" target="_blank">Testowanie przy pomocy Test Managera</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://msdn.microsoft.com/en-us/library/hh301769%28v=vs.110%29.aspx" target="_blank">Zarządzanie kontaktem z klientem (Feedback Manager) - tutorial</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://blogs.msdn.com/b/bharry/archive/2011/09/19/the-new-team-explorer-in-tfs-11.aspx" target="_blank">Zmiany w Team Explorerze oraz opis Code Review</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://blogs.msdn.com/b/bharry/archive/2011/08/31/merge-enhancements-in-tfs-11.aspx" target="_blank">Nowy mechanizm merge'owania plików</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://blogs.msdn.com/b/bharry/archive/2011/09/01/wrapping-up-tfs-11-version-control-improvements.aspx" target="_blank">Podsumowanie zmian w kontroli wersji</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://www.woodwardweb.com/vsts/getting_started.html" target="_blank">Raporty z TFS przy użyciu Excela</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://blogs.msdn.com/b/briankel/archive/2011/09/16/visual-studio-11-application-lifecycle-management-virtual-machine-and-hands-on-labs-demo-scripts.aspx" target="_blank">Maszyna wirtualna z przykładową konfiguracją TFS oraz sporo tutoriali</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Polecam również dwie świetne książki (dotyczą one co prawda TFS 2010, ale większość porad i opisów ma również zastosowanie w przypadku nowej wersji):</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://www.amazon.com/Professional-Scrum-Foundation-Server-Programmer/dp/0470943335" target="_blank">"Professional Scrum with Team Foundation Server 2010" - S.Resnick, A. Bjork, M. de la Maza </a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://www.amazon.com/Professional-Team-Foundation-Server-Programmer/dp/0470943327/ref=sr_1_sc_1?s=books&ie=UTF8&qid=1332490618&sr=1-1-spell" target="_blank">"Proffesional Team Foundation Server 2010" - E. Blankenship, M. Woodward, G. Holliday, B. Keller</a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Miłej lektury!</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"> </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><span id="goog_957396288"></span><span id="goog_957396289"></span><a href="http://www.blogger.com/"></a></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
</div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com1tag:blogger.com,1999:blog-8979460837090429655.post-44704250470366360882012-02-05T22:48:00.000+01:002012-02-05T22:48:10.413+01:00Multiplatforomowe aplikacje w .NET, Silverlight i Windows Phone Cz.3 - Konfiguracja komunikacji socketami<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">Wstęp</span></b></span><br />
<br />
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">W poprzednich dwóch wpisach, przedstawiłem ogólne zasady tworzenia aplikacji multiplatformowych, pokazałem jak można zapisywać i odczytywać dane z socketów. Oparłem się przy tym mocno na <a href="http://channel9.msdn.com/Shows/SilverlightTV/Silverlight-TV-70-Sockets-Unplugged">przykładzie Johna Papa</a>. W tym przykładzie pójdę dalej tym tropem i pokażę jak można uruchomić komunikację klient serwer. Jak sprawić, żeby sockety zaczęły nasłuchiwać i ze sobą rozmawiać.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">Odczyt/zapis socketa</span></b></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">W poprzednim wpisie przedstawiłem dwie klasy do odczytywania poleceń przesyłanych przez sockety (kody źródłowe dostępne są <a href="http://joomanji.no-ip.org/blog/multiplatform02.zip">tutaj</a>), Ponieważ nasze sockety będą miały komunikować się dwustronnie dla uproszczenia sprawy wprowadźmy jeszcze dodatkową klasę opakowującą CommandReaderWriter.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public class CommandReaderWriter
{
public Socket Socket { get; protected set; }
public delegate void OnConnectedDelegate(object sender, SocketAsyncEventArgs e);
public event OnConnectedDelegate OnConnectedEvent = delegate { };
public CommandReader Reader { get; protected set; }
public CommandWriter Writer { get; protected set; }
public CommandReaderWriter()
{
}
public CommandReaderWriter(Socket socket)
{
InitializeConnection(socket);
}
/// <summary>
/// Metoda inicjująca połączenie z konkretnym socketem
/// </summary>
/// <param name="socket"></param>
public void InitializeConnection(Socket socket)
{
Reader = new CommandReader(socket);
Writer = new CommandWriter(socket);
}
/// <summary>
/// Metoda inicjująca połączenie z socketem
/// znajdującym się pod wskazany adresem i portem
/// </summary>
/// <param name="serverName">adres serwera</param>
/// <param name="port">port</param>
public void InitializeConnection(string serverName, int port)
{
var s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var e = new SocketAsyncEventArgs
{
RemoteEndPoint = new DnsEndPoint(serverName, port)
};
e.Completed += OnConnected;
s.ConnectAsync(e);
}
/// <summary>
/// Metoda obsługująca zdarzenie połączenia się z socketem
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnConnected(object sender, SocketAsyncEventArgs e)
{
Socket s = (Socket)sender;
if (e.SocketError != SocketError.Success)
{
throw new Exception("Nie udało się połączyć!");
}
InitializeConnection(s);
OnConnectedEvent(this, e);
}
/// <summary>
/// Metoda zakańczająca nasłuchiwanie socketu
/// </summary>
public void StopReading()
{
Reader.StopReading();
}
/// <summary>
/// Metoda rozpoczynająca nasłuchiwanie socketu
/// </summary>
/// <param name="h"></param>
public void StartListening(ICommandHandler h)
{
Reader.StartListening(h);
}
/// <summary>
/// Metoda wysyłająca polecenie poprzez socket
/// przekazany w konstruktorze
/// </summary>
/// <param name="command">polecenie</param>
public void Write(Command command)
{
Writer.Write(command);
}
public void DoCommand(CommandReader r, Command cmd)
{
//tutaj dodana zostanie obsługi polecenia
}
}
</pre>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Klasa ta oprócz opakowania metod CommandReader i CommandWriter posiada też metody odpowiedzialne za jego inicjalizację. Ta z adresem i numerem portu powinna być używana przez aplikację kliencką, ta z Socketem w aplikacji serwerowej. </span><br />
<span style="font-family: Verdana,sans-serif;">Mamy już tak naprawdę komplet klas, które pozwolą nam na odczytywanie i zapisywanie z socketów. Musimy teraz utworzyć klasy, które je nam wywołają.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;"><b>Konfiguracja klienta</b></span></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Zacznijmy od sprawy prostszej - konfiguracji klienta. Otwórzmy definicję głównego okna aplikacji Multiplatform.Client.Silverlight - MainPage.xaml.cs i zmodyfikujmy je następująco:</span><br />
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public partial class MainPage : UserControl, ICommandHandler
{
private CommandReaderWriter _commandReaderWriter;
public MainPage()
{
InitializeComponent();
InitializeNetworkConnection();
}
/// <summary>
/// Metoda inicjująca połączenie z serwerem
/// </summary>
private void InitializeNetworkConnection()
{
_commandReaderWriter = new CommandReaderWriter();
_commandReaderWriter.InitializeConnection("localhost", 4529);
_commandReaderWriter.OnConnectedEvent += CommandReaderWriter_OnConnectedEvent;
}
/// <summary>
/// Metoda przechwytująca zdarzenie połączenia z serwerem
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CommandReaderWriter_OnConnectedEvent(object sender, SocketAsyncEventArgs e)
{
//skoro udało się połączyć, to rozpocznij nasłuchiwanie
_commandReaderWriter.StartListening(this);
}
public void DoCommand(CommandReader r, Command cmd)
{
//tutaj będzie obsługa poleceń
}
}
</pre>
<br />
<span style="font-family: Verdana,sans-serif;">Dodaliśmy do niego zainicjowanie połączenia z serwerem poprzez podanie adresu oraz numeru portu, na którym będziemy nasłuchiwać. Klasa ta implementuje również interfejs ICommandHandler, dzięki czemu może obsługiwać polecenia wysłane przez serwer.</span><br />
<span style="font-family: Verdana,sans-serif;">Dokładnie to samo moglibyśmy zrobić w przypadku MainWindow aplikacji WPF oraz MainPage w aplikacji na Phone'a, z małym wyjątkiem w przypadku tego ostatniego. Nie możemy podać jako adres serwera "localhost", gdyż emulator telefonu potraktuje to jako odwołanie się do siebie, a nie do naszego komputera. Możemy to łatwo obejść wpisując zamiast "localhost" nazwę sieciową naszego komputera. Należy uważać też na numer portu, ale o tym szerzej w kolejnym punkcie.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;"> </span><br />
<span style="font-family: Verdana,sans-serif;"> <b><span style="font-size: large;">Konfiguracja serwera</span></b></span><br />
<span style="font-family: Verdana,sans-serif;"> </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Serwer w swoim zachowaniu będzie zbliżony do klienta, poza tym, że będzie musiał rozpocząć nasłuchiwanie na połączenie z klientem, a nie łączyć się bezpośrednio z nim. Utwórzmy nowy katalog solucji "Server" oraz nowy projekt "Multiplatform.Server" typu "Class Library". Dodajmy klasę ServerProgram - będzie ona odpowiadała za rozpoczęcie nasłuchiwania oraz obsługę poleceń od klienta. Powinna ona wyglądać następująco:</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public class ServerProgram : ICommandHandler
{
readonly TcpListener _server = new TcpListener(IPAddress.Any, 4529);
private CommandReaderWriter _commandReaderWriter;
void Run()
{
_server.Start();
while (true)
{
Socket s = _server.AcceptSocket();
_commandReaderWriter = new CommandReaderWriter(s);
_commandReaderWriter.StartListening(this);
}
}
/// <summary>
/// Statyczna metoda tworząca nową instancję serwera
/// </summary>
public static void Start()
{
Console.WriteLine("Starting PictureHunt Server on port 4529");
var p = new ServerProgram();
p.Run();
}
/// <summary>
/// Metoda obsługująca polecenie od klienta
/// </summary>
/// <param name="r"></param>
/// <param name="cmd"></param>
public void DoCommand(CommandReader r, Command cmd)
{
//tutaj będziemy obsługiwać polecenie
}
}
</pre>
<br />
<span style="font-family: Verdana,sans-serif;">Utwórzmy jeszcze projekt Multiplatform.Server.Host w katalogu solucji Server, który będzie uruchamiał metodę Start naszego Servera w swojej metodzie Main (oszczędzę sobie trudu wklejania, a Wam czytania tej jakże zawiłej klasy).</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;"><b>Wprawiamy to wszystko w ruch</b></span></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Mamy już zatem 3 rodzaje klientów - WPF, Silverlight, Phone oraz serwer. Co prawda jest to póki co dosyć oszukany serwer bo może obsłużyć, ale zawsze... </span><br />
<span style="font-family: Verdana,sans-serif;">Wypadało by teraz zrobić jakąś własną komendę, dzięki której będziemy mogli przetestować czy nasz szkielet, ma już mięśnie, czy dalej odmawia uczynienia choćby małego ruchu. Zróbmy klasę we współdzielonym projekcie TextCommand, będzie ona pozwalała na przesłanie tekstu.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public class TextCommand : Command
{
public string Text { get; set; }
public TextCommand()
{
CommandType = 1;
}
public TextCommand(string text) : this()
{
Text = text;
// tutaj powinna być serializacja binarna
// obiektu Text i przypisanie do tablicy Data
}
}
</pre>
<br />
<span style="font-family: Verdana,sans-serif;">Jak widzimy jest to bardzo prosta klasa. Dziedziczy po klasie Command, ma konstruktor domyślny oraz przyjmujący parametr z tekstem, który chcemy przesłać. Na pewno was zastanawia dlaczego nie zrobiłem tutaj standardowej serializacji przy pomocy BinaryFormattera. Otóż nie mogłem tego zrobić, bo z nieznanych mi powodów w Silverlight tej klasy nie ma. Można kombinować i robić <a href="http://www.eggheadcafe.com/tutorials/xaml/96487d4c-d92f-4ca5-85b7-0fef6f42d6c3/silverlight-binary-serialization-and-compression-with-wcf-services.aspx">hacki stosując serializację WCFową</a>, ja jednak polecam użycie Open Source'owej biblioteki <a href="http://www.sharpserializer.com/en/index.html">SharpSerializer</a>. Pozwala ona na całkiem sprawną i szybką serializację zarówno w zwykłych projektach .NETowych jak i Silverlight, Windows Phone.</span><br />
<span style="font-family: Verdana,sans-serif;">Po pobraniu i dołączeniu plików dll do projektów dodajmy klasę opakowującą do dla tej biblioteki.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;"> </span><br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public static class BinaryUtils
{
private static readonly SharpSerializer SharpSerializer = new SharpSerializer(true);
public static byte[] Serialize(object obj)
{
using (var memoryStream = new MemoryStream())
{
SharpSerializer.Serialize(obj, memoryStream);
return memoryStream.GetBuffer();
}
}
public static object Deserialize(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
return SharpSerializer.Deserialize(memoryStream);
}
}
}
</pre>
<br />
<span style="font-family: Verdana,sans-serif;"></span><br />
<span style="font-family: Verdana,sans-serif;">Jak widać, użycie biblioteki jest banalnie proste, nie wymaga specjalnego tłumaczenia. Mając to już gotowe, możemy dodać serializację tekstu w konstruktorze naszej klasy TextCommand. Ostatecznie wygląda on:</span></div>
<div style="text-align: justify;">
<br /></div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public TextCommand(string text) : this()
{
Text = text;
Data = BinaryUtils.Serialize(Text);
}
</pre>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Dodajmy więc prostą funkcjonalność przesyłania tej komendy pomiędzy klientem a serwerem i odwrotnie. Klient po nawiązaniu połączenia wyśle wiadomość "Ping", serwer mu odpowie wiadomością "Pong". Musimy dokonać zmian w obsłudze Poleceń zarówno po stronie klienckiej ja i stronie serwerowej.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Klasa okna klienta wyglądało będzie po zmianach:</span></div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public partial class MainWindow : Window, ICommandHandler
{
private CommandReaderWriter _commandReaderWriter;
public MainWindow()
{
InitializeComponent();
InitializeNetworkConnection();
}
/// <summary>
/// Metoda inicjująca połączenie z serwerem
/// </summary>
private void InitializeNetworkConnection()
{
_commandReaderWriter = new CommandReaderWriter();
_commandReaderWriter.InitializeConnection("localhost", 4529);
_commandReaderWriter.OnConnectedEvent += CommandReaderWriter_OnConnectedEvent;
}
/// <summary>
/// Metoda przechwytująca zdarzenie połączenia z serwerem
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CommandReaderWriter_OnConnectedEvent(object sender, SocketAsyncEventArgs e)
{
//skoro udało się połączyć, to rozpocznij nasłuchiwanie
_commandReaderWriter.StartListening(this);
_commandReaderWriter.Write(new TextCommand("Ping!")); // 1.
}
public void DoCommand(CommandReader r, Command cmd)
{
switch (cmd.CommandType)
{
case 1:
string text = (string)BinaryUtils.Deserialize(cmd.Data); //2
Debug.WriteLine(text);
break;
}
}
}
</pre>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Dodałem przesłanie polecenia z tekstem po nawiązaniu połączenia z serwerem (oznaczone numerem 1) oraz przechwycenie polecenia z serwera i obsłużenie go (oznaczone numerem 2). Analogicznie klasa serwera po zmianach będzie wyglądała:</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public class ServerProgram : ICommandHandler
{
readonly TcpListener _server = new TcpListener(IPAddress.Any, 4529);
private CommandReaderWriter _commandReaderWriter;
void Run()
{
_server.Start();
while (true)
{
Socket s = _server.AcceptSocket();
_commandReaderWriter = new CommandReaderWriter(s);
_commandReaderWriter.StartListening(this);
}
}
/// <summary>
/// Statyczna metoda tworząca nową instancję serwera
/// </summary>
public static void Start()
{
Console.WriteLine("Starting PictureHunt Server on port 4529");
var p = new ServerProgram();
p.Run();
}
/// <summary>
/// Metoda obsługująca polecenie od klienta
/// </summary>
/// <param name="r"></param>
/// <param name="cmd"></param>
public void DoCommand(CommandReader r, Command cmd)
{
switch (cmd.CommandType)
{
case 1:
string text = (string)BinaryUtils.Deserialize(cmd.Data);
Console.WriteLine(text);
//odpowiedz klientowi "Pong!"
_commandReaderWriter.Write(new TextCommand("Pong!"));
break;
}
}
}
</pre>
<span style="font-family: Verdana,sans-serif;">Pozostało nam tylko dodać jeszcze obsługę naszego polecenia w CommandReaderze w metodzie TransformData</span></div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">private void TransformData(SocketAsyncEventArgs e)
{
[...]
while (data.Length >= 12)
{
[...]
//zainicjuj obiekt polecenia
Command cmd = null;
switch (opcode)
{
case 1:
cmd = new TextCommand {Data = newData};
break;
default:
cmd = new Command{Data = newData};
break;
}
[...]
}
}
</pre>
<span style="font-family: Verdana,sans-serif;">Możecie śmiało odpalić serwer, i jedną z aplikacji klienckich, wszędzie zadziała dobrze oprócz Silverlighta. Dlaczego? Wytłumaczenie znajdziecie w kolejnym punkcie...</span><br />
<br />
<b><span style="font-family: Verdana,sans-serif;">Silverlight i Sockety</span></b><br />
<span style="font-family: Verdana,sans-serif;"> </span><br />
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"> Silverlight jako chyba najbardziej irytująca technologia Microsoftu i tutaj musi utrudniać programistom życie. Oczywiście celem jest dobro i bezpieczeństwo użytkowników końcowych. Ja jednak nie do końca ufam i nie do końca wierzę tym tłumaczeniom, skoro w Windows Phone nie ma już takich utrudnień związanych z socketami.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Szczegółowo można przeczytać na ten temat w artykule <a href="http://msdn.microsoft.com/en-us/library/cc645032%28VS.95%29.aspx">Network Security Access Restrictions in Silverlight na MSDN</a> - ja postaram się to skrócić w kilku zdaniach. Aby zachować bezpieczeństwo i wygodę użytkowników w Silverlight można łączyć się z Socketami tylko z zakresu 4502-4534. Dodatkowo aplikacja Silverlightowa łącząca się z serwerem na zadanym adresie i zadanym porcie najpierw próbuje połączyć się z tym adresem z portem 943. Oczekuje, że na tym porcie będzie wystawiona usługa, która mu dostarczy plik xml z informacjami o zasadach bezpieczeństwa (tzw. "policy file").</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Jeżeli nie odnajdzie tej usługi i nie pobierze tego pliku, to automatycznie ignoruje połączenie uznając, że jest ono niebezpieczne. Wszystko dla naszego dobra, oczywiście.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Nie będę tutaj wklejał tego kodu, jest on dostępny w przedstawionym wcześniej artykule, oraz w kodach źródłowych na końcu artykułu. Należy pamiętać, żeby usługa ta była zawsze uruchomiona na tym samym adresie co nasz serwer.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<b><span style="font-family: Verdana,sans-serif;">Podsumowanie</span></b></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">W tym artykule pokazałem już jak wprawić w ruch machinę komunikacji socketami pomiędzy klientem a serwerem i serwerem a klientem. W kolejnych artykułach przedstawię jak zrobić serwer obsługujący wielu użytkowników oraz jak ukryć za fasadą tą niezbyt elegancką obsługę komend.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Kody źródłowe możecie pobrać <a href="http://joomanji.no-ip.org/blog/Multiplatform03.zip">stąd</a>. </span></div>
</div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-19470859168145927222012-02-05T16:15:00.001+01:002012-02-05T18:38:10.125+01:00Multiplatforomowe aplikacje w .NET, Silverlight i Windows Phone Cz.2 - Wstęp do komunikacji socketami<div dir="ltr" style="text-align: left;" trbidi="on">
<b><span style="font-family: Verdana,sans-serif; font-size: large;">Wstęp</span></b><br />
<div style="text-align: justify;">
<br />
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">W
poprzednim wpisie przedstawiłem wstęp oraz kilka problemów, które
napotykamy przy rozpoczęciu zabawy z aplikacji wieloplatformowych. Tak
jak zapowiedziałem, w tym wpisie przedstawię kolejny krok do utworzenia
gry multiplayer w Kuku. Tym razem na warsztat wzięte zostają metody
komunikacji klient-serwer, serwer-klient przy pomocy socketów. Dlaczego
przy pomocy socketów, a nie WCF? Szczegóły później. Najpierw się
zastanówmy czego tak naprawdę potrzebujemy.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;"> </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">Naszą wersję Kuku można opisać następująco:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">- zbierają się gracze,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">- każdemu z nich rozdajemy karty, pierwszy gracz dostaje 4, resta 3,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">- jeżeli któryś z graczy ma 3 karty w jednym kolorze lub z tymi samymi figurami, to może krzyknąć "kuku!". </span><span style="font-family: Verdana,sans-serif; font-size: small;">Jeżeli nikt tego nie zrobił, to</span><span style="font-family: Verdana,sans-serif; font-size: small;"> </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">- zaczyna się tura pierwszego gracza,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">- wybiera on jedną kartę i przekazuje ją kolejnemu graczowi,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">- zaczyna się jego tura,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">- jeśli karta do niego wróci, może ją wymienić,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">- kto pierwszy skompletuje kuku ten wygrywa.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">Zatem nasza gra powinna:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">- umożliwić dołączanie graczy,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif; font-size: small;">- reagować na wybory gracza,</span></div>
<div style="text-align: justify;">
<div style="font-family: Verdana,sans-serif;">
<span style="font-size: small;">- powiadamiać graczy o zmianie stanu gry. </span></div>
<div style="font-family: Verdana,sans-serif;">
<br /></div>
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">Potrzebujemy zatem komunikacji pomiędzy graczami. Niektórym z Was od razu może się to skojarzyć z grami/programami typu P2P (Peer To Peer). Będzie to bardzo dobre skojarzenie. Implementując nasz system można by było w teorii pokusić się o to, żeby gracz, wysyłał kolejnemu graczowi informację: "Stary teraz twoja kolej!". A pozostałym o tym, że to zrobił. Niestety takie systemy są trudne do utrzymania, kontroli i rozwoju. Dodatkowo cała logika biznesowa jest przechowywana w aplikacji klienckiej, co powoduje ich nadmierny rozrost, tworząc je za dużymi do zastosowania na stronach internetowych oraz telefonach komórkowych. Według mnie lepsze jest rozwiązanie pośrednie:</span></span></div>
</div>
<div style="text-align: justify;">
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">- gracz przesyła informację do serwera o swoim wyborze,</span></span></div>
<div style="text-align: justify;">
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">- serwer decyduje o tym jaka akcja powinna być wykonana - to on mówi kolejnemu graczowi o jego turze, on rozsyła informacje do pozostałych graczy.</span></span></div>
<div style="text-align: justify;">
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">Komunikacja musi być zatem dwustronna:</span></span></div>
<div style="text-align: justify;">
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">- klient - serwer</span></span></div>
<div style="text-align: justify;">
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">- serwer - klient</span></span></div>
<div style="text-align: justify;">
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-yC2Mufy46GA/Ty5yePrIr3I/AAAAAAAAAT4/xHBq2Vk9hRk/s1600/14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="245" src="http://1.bp.blogspot.com/-yC2Mufy46GA/Ty5yePrIr3I/AAAAAAAAAT4/xHBq2Vk9hRk/s400/14.png" width="400" /></a></div>
<br /></div>
<div style="text-align: justify;">
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">Podejrzewam, że większość z Was miała już do czynienia z web service'ami pisanymi przy pomocy WCF. Są one dobre dla standardowych rozwiązań biznesowych, w których wysyłamy zapytanie, dostajemy odpowiedź - typowa komunikacja jednostronna. Niestety ten model komunikacji nie sprawdzi się w przypadku naszego problemu. U nas żądania wysyłane są w dwie strony, nie wiemy również kiedy dokładnie one wystąpią. Niektórzy z Was zapewne natrafili na Duplex Channel, pozwalający oprogramować w WCF komunikację dwustronną. Niestety w Silverlight dostępna jest tylko jego uboższa wersja, mając dużo ograniczeń, nie nadająca się do rozwiązań komercyjnych (więcej szczegółów na blogu Tomasza Janczuka <a href="http://tomasz.janczuk.org/2009/07/pubsub-sample-using-http-polling-duplex.html">tutaj</a> i <a href="http://tomasz.janczuk.org/2009/11/wcf-nettcp-protocol-in-silverlight-4.html">tutaj</a>). Z pomocą przyjdą nam stare jak świat sockety.</span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b><span style="font-size: large;"><span style="font-family: Verdana,sans-serif;">Sockety </span></span></b><br />
<br />
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;"><span style="font-size: small;">Jest to </span>rozwiązanie znane od dawien dawna, istnieje ono zarówno w C++ jak i w Javie. Nie będę się nad tym przesadnie rozpisywał, raczej przedstawię ich ogólną zasadę.</span></span></div>
<div style="text-align: justify;">
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">Sockety pozwalają na bezpośrednią komunikację pomiędzy dwoma komputerami. Aby nawiązać połączenie musimy znać adres internetowy komputera oraz port, na którym on nasłuchuje. Klient znając te dane serwera łączy się z nim. Tworzone jest połączenie TCP. Połączenie jest utrzymywane cały czas, dlatego też możliwa jest komunikacja w dwie strony. Odbywa się ona przy pomocy strumienia bajtów. Zalety tego rozwiązania to szybkość i wydajność, minusem jest to, że musimy oprogramować cały mechanizm "odszyfrowywania" strumienia. Musimy sami określać, które bajty odpowiadają za co, gdzie kończy się jedno rozwiązanie, a zaczyna kolejne.</span></span></div>
<div style="text-align: justify;">
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">W moich rozważaniach punktem wyjściowym będzie świetny przykład Johna Papa zaprezentowany na <a href="http://channel9.msdn.com/Shows/SilverlightTV/Silverlight-TV-70-Sockets-Unplugged">Silverlight TV</a>. Przedstawił on tam podstawowy mechanizm przetwarzania socketów, zachęcam do przyjrzenia się mu i porównania ze zmianami, które do niego wprowadziłem.</span></span></div>
<div style="text-align: justify;">
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">Zaproponował on bardzo sprytny i prosty zarazem sposób przetwarzania danych przesyłanych w socketach, wykorzystał on przy tym <a href="http://pl.wikipedia.org/wiki/Polecenie_%28wzorzec_projektowy%29">wzorzec projektowy Polecenie (Command).</a></span></span><br />
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">Chcąc przesłać żądanie do serwera musimy utworzyć obiekt klasy Command. Następnie serializujemy go do postaci binarnej i przesyłamy go poprzez socket do serwera. Serwer odbiera bajty i deserializuje je. Tak utworzony obiekt polecenia przetwarzamy przy pomocy klasy pomocniczej CommandHandler. Dla każdego rodzaju operacji konieczne jest utworzenie implementacji klasy Command, dzięki temu klasa pomocnicza wie w jaki sposób ma wykonać polecenie (na podstawie jej typu).</span></span><br />
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">Wspominałem wcześniej, że największym problemem przy Socketach jest określenie, w jaki sposób rozdzielić jedno żądanie od innego. Tak jak już napisałem pomiędzy klientem a serwerem utworzony jest strumień TCP. Zwykle każde żądanie jest wysyłane osobno, lecz może dość do sytuacji gdy w jednym pakiecie wysłane zostanie kilka żądań (np. gdy są opóźnienia w sieci a klient wykonał szybko kilka akcji), lub jedno żądanie zostanie podzielone na kilka pakietów (np. gdy wysyłamy sporą liczbę danych). Nie będziemy wiedzieli więc od razu po odczytaniu danych ze strumienia, czy możemy już deserializować i wykonać Polecenie. Jak zatem sobie z tym poradzić? </span></span><br />
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">John Papa zaproponował, żeby komenda posiadała nagłówek. Nagłówek ten posiadał będzie podstawowe informacje o niej (takie jak jej rozmiar). Najważniejszą jego cechą jest to, że będzie on miał stałą wielkość. Dzięki czemu będzie można go zserializować od razu gdy zorientujemy się, że mamy do czynienia z nowym żądaniem. Po jego odczytaniu będziemy wiedzieć ile jeszcze bajtów zostało nam do odczytania, wiedząc tym samym, w którym miejscu kończy się żądanie. </span></span><br />
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;"><br /></span></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-Hckf6_Eot-A/Ty6EUQoGR5I/AAAAAAAAAUA/qjRwoWWOGfA/s1600/15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://4.bp.blogspot.com/-Hckf6_Eot-A/Ty6EUQoGR5I/AAAAAAAAAUA/qjRwoWWOGfA/s400/15.png" width="330" /></a></div>
<br />
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">Konkrety</span></b></span><br />
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;"></span></span><br />
<br />
<span style="font-size: small;"><span style="font-family: Verdana,sans-serif;">Klasa polecenia napisana zgodnie z tymi wytycznymi wygląda następująco:</span></span></div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">/// <summary>
/// Klasa wzorowana na rozwiązaniu przedstawionym
/// przez Johna Papa w Silverlight TV
/// http://channel9.msdn.com/Shows/SilverlightTV/Silverlight-TV-70-Sockets-Unplugged
/// </summary>
public class Command
{
/// <summary>
/// Typ polecenia
///
public int CommandType;
/// <summary>
/// Rozmiar nagłówka
/// </summary>
public int HeaderLen;
/// <summary>
/// Dane nagłówka
/// </summary>
public byte[] Header;
/// <summary>
/// Dane polecenia
/// </summary>
public byte[] Data;
public Command()
{
HeaderLen = 12;
Header = null;
Data = null;
}
/// <summary>
/// Metoda inicjująca nagłówek
/// </summary>
/// <returns></returns>
public virtual BinaryWriter InitHeader()
{
Debug.Assert(CommandType != 0);
Debug.Assert(HeaderLen >= 12);
Header = new byte[HeaderLen];
var bw = new BinaryWriter(new MemoryStream(Header));
bw.Write(Htonl(HeaderLen));
bw.Write(Htonl(Data == null ? 0 : Data.Length));
bw.Write(Htonl(CommandType));
return bw;
}
/// <summary>
/// Metoda formatująca liczby do formatu
/// odpowiedzniego dla socketów
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public Int32 Htonl(Int32 value)
{
return IPAddress.HostToNetworkOrder(value);
}
}
</pre>
<div>
<br />
<div style="font-family: Verdana,sans-serif;">
Do zapisywania wysłania polecenia przez Socket służy klasa CommandWriter
</div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">/// <summary>
/// Klasa służąca do wysyłania danych poprzez socket
/// </summary>
public class CommandWriter
{
public Socket Socket;
public CommandWriter()
{
}
public CommandWriter(Socket socket)
{
Socket = socket;
}
/// <summary>
/// Metoda wysyłająca polecenie poprzez socket
/// przekazany w konstruktorze
/// </summary>
/// <param name="command">polecenie</param>
public void Write(Command command)
{
Write(Socket, command);
}
/// <summary>
/// Metoda wysyłająca polecenie poprzez
/// zadany socket
/// </summary>
/// <param name="socket">socket</param>
/// <param name="command">polecenie</param>
public void Write(Socket socket, Command command)
{
//utwórz nagłówek
command.InitHeader();
var senddata = new List<ArraySegment<byte>> { new ArraySegment<byte>(command.Header) };
//wrzuć dane polecenia
if (command.Data != null)
{
senddata.Add(new ArraySegment<byte>(command.Data));
}
var writeEventArgs = new SocketAsyncEventArgs();
writeEventArgs.Completed += WriteCompleted;
writeEventArgs.BufferList = senddata;
//wyślij socketem bajty
socket.SendAsync(writeEventArgs);
}
}
</pre>
<div style="font-family: Verdana,sans-serif;">
Klasa odczytująca polecenie z socketa będzie wyglądała następująco:
</div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">/// <summary>
/// Klasa służaca do odczytywania danych z socketa
/// wzorowana na rozwiązaniu przedstawionym
/// przez Johna Papa w Silverlight TV
/// http://channel9.msdn.com/Shows/SilverlightTV/Silverlight-TV-70-Sockets-Unplugged
/// </summary>
public class CommandReader
{
public Socket Socket;
byte[] data = new byte[0];
public CommandReader(Socket socket)
{
this.Socket = socket;
}
/// <summary>
/// Metoda zamieniająca liczbę z formatu socketa
/// na format standardowy
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static Int32 Ntohl(Int32 value)
{
return System.Net.IPAddress.NetworkToHostOrder(value);
}
/// <summary>
/// Metoda rozpoczynająca nasłuchiwanie socketu
/// </summary>
/// <param name="h"></param>
public void StartListening(ICommandHandler h)
{
Console.WriteLine("CR: Go : Socket {0} CR {1}", Socket, this);
//określ parametry nasłuchiwania
const int size = 10000;
var e = new SocketAsyncEventArgs();
e.Completed += OnRead;
e.UserToken = h;
e.SetBuffer(new byte[size], 0, size);
//rozpocznij nasłuchiwanie
while (Socket.ReceiveAsync(e) == false)
{
TransformData(e);
}
}
/// <summary>
/// Metoda wywołana po zaczytaniu paczki danych z socketa
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnRead(object sender, SocketAsyncEventArgs e)
{
//przetwarzaj dane
TransformData(e);
//nasłuchuj czy nie przychodzą kolejne porcje danych
while (Socket != null && Socket.ReceiveAsync(e) == false)
{
TransformData(e);
if (e.BytesTransferred == 0)
{
break;
}
}
}
/// <summary>
/// Metoda przetwarzająca dane otrzymane z socketa
/// </summary>
/// <param name="e"></param>
private void TransformData(SocketAsyncEventArgs e)
{
var oldLen = data.Length;
var newLen = oldLen + e.BytesTransferred;
Array.Resize<byte>(ref data, newLen);
Array.Copy(e.Buffer, 0, data, oldLen, e.BytesTransferred);
while (data.Length >= 12)
{
//pobrano już co najmniej nagłówek
var reader = new BinaryReader(new MemoryStream(data));
var headerLen = Ntohl(reader.ReadInt32());
var dataLen = Ntohl(reader.ReadInt32());
var opcode = Ntohl(reader.ReadInt32());
var totLen = headerLen + dataLen;
var extra = data.Length - totLen;
//jeżeli nie pobrano jeszcze całości danych
//zakończ przetwarzanie i czekaj na kolejną
//paczkę z danymi
if (extra < 0)
break;
//Pobrano już co najmniej tyle danych ile ma polecenie
//utwórz nową tablicę do przechowywania danych polecenia
byte[] newData = new Byte[dataLen];
Array.Copy(data, headerLen, newData, 0, dataLen);
//zainicjuj obiekt polecenia
Command cmd = null;
switch (opcode)
{
//tutaj wstawiamy tworzenie poszczególnych poleceń
//w zależności od typu
default:
cmd = new Command{Data = newData};
break;
}
//jeżeli pobrano więcej bajtów niż miało mieć polecenie
//przenieś je do nowej tablicy
if (extra > 0)
{
Array.Copy(data, totLen, data, 0, extra);
}
Array.Resize<byte>(ref data, extra);
//wykonaj polecenie
ICommandHandler h = (ICommandHandler)e.UserToken;
h.DoCommand(this, cmd);
}
}
}
</pre>
<div>
<br />
<div style="font-family: Verdana,sans-serif;">
<b>Podsumowanie</b></div>
<div style="font-family: Verdana,sans-serif;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
W tym poście przedstawiłem ogólny zarys sposobu komunikacji dla aplikacji multiplatformowych w środowisku .NET. Pokazane zostało po co nam komunikacja dwustronna, klient - serwer, serwer - klient. Jak można zaimplementować ją przy pomocy socketów.</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
Popisałem się również umiejętnością czytania ze zrozumieniem i pokazałem klasy do obsługi czytania i zapisu do socketów zaprezentowane przez Johna Papa. W kolejnych postach przedstawię jak w ogóle uruchomić sockety, jak skonfigurować serwer i klienta i pokażę trochę własnej inwencji przedstawiając swoje ulepszenia do dotychczas opisanych rozwiązań.<br />
<br />
Kody źródłowe można pobrać <a href="http://joomanji.no-ip.org/blog/multiplatform02.zip">tutaj</a>. </div>
</div>
</div>
</div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-27580816951898937362012-02-05T10:26:00.000+01:002012-02-05T10:51:01.513+01:00Multiplatforomowe aplikacje w .NET, Silverlight i Windows Phone Cz.1 - Współdzielenie klas<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;">Wstęp</span> </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">W kilku najbliższych wpisach postaram się przybliżyć tematykę tworzenia aplikacji multiplatformowych. Środowisko .NET dostarcza nam rozwiązań, które pozwalają tworzyć zarówno aplikacje okienkowe (WinForms, WPF), strony internetowe (ASP.NET, Siverlight) jak i programy na telefony komórkowe (Windows Phone). W dzisiejszych czasach rozpowszechniło się tworzenie aplikacji w architekturze trójwarstwowej. Dzięki niej zostaje rozdzielony dostęp do danych, logika biznesowa oraz warstwa kliencka. Ułatwia to bardzo stworzenie systemów, które będą mogły "wystawiać" środowiska klienckie na różne platformy technologiczne. Brzmi prosto, ale w praktyce okazuje się trudniejsze. Programiści muszą cały czas się pilnować i mieć świadomość tego co się robi.Według mnie najważniejsze rzeczy, które powinniśmy mieć cały czas "w głowie" przy tworzeniu systemów wieloplatformowych są:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- możliwość wielokrotnego używania tych samych klas w różnych rodzajach projektów,</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- tak jak tort, cebula i ogry, nasza aplikacja powinna posiadać warstwy. Warstwy te powinny komunikować się z sąsiednimi, nie burząc łańcucha zależności</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- łatwość refaktoryzacji. Twórzmy rozwiązania w ten sposób, żeby np. zmiana typu bazy danych nie pociągała za sobą zmian w aplikacji klienckiej</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Oczywiście jak we wszystkim, tutaj również trzeba kierować się rozsądkiem. Nie należy tworzyć rozwiązań, które pozwolą nam oprogramować działanie świata i rozpracować teorię wielkiego wybuchu, gdy chcemy napisać prosty kalkulator. Tak samo nie ma sensu generować kilkudziesięciu warstw, do których spamiętania będziemy potrzebowali schematu na dwie kartki A0. </span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">.NET umożliwia nam tworzenie aplikacji w różnych platformach klienckich, ale żeby nie było tak prosto do każdego z nich ma pewne obwarowania. Silverlight, WPF i Windows Phone wywodzą się z jednego pnia, ale są osobnymi gałęziami. Z różnych powodów, głównie związanych ze specyfiką technologiczną środowiska klienckiego, oraz zaszłościami historycznymi są to tak naprawdę 3 różne frameworki .NET. Współdzielą niektóre klasy, część mają innych. W dużym uogólnieniu można by było powiedzieć:</span><br />
<span style="font-family: Verdana,sans-serif;">- Silverlight jest podzbiorem WPF,</span><br />
<span style="font-family: Verdana,sans-serif;">- Windows Phone jest podzbiorem Silverlight.</span><br />
<span style="font-family: Verdana,sans-serif;">Oczywiście nie jest to do końca prawdą, ale całkiem dobrze oddaje rzeczywistość bez wchodzenia w większe szczegóły.</span><span style="font-family: Verdana,sans-serif;"> No ale przejdźmy wreszcie do przykładów przykładu. Na nim powinno być łatwiej przedstawić te problemy. Graliście kiedyś w Kuku? Nie? To proszę oto i zasady (znalezione na <a href="http://www.abc-gier-karcianych.kasyno-gier.pl/kuku.php">"ABC Gier Karcianych"</a>):</span><br />
<br />
<span style="font-family: Verdana,sans-serif;"></span><br />
<i><span style="font-family: Verdana,sans-serif;">"Kuku jest bardzo prostą grą karcianą trwającą zazwyczaj około 10 - 15 minut. Celem gry Kuku jest skompletowanie trzech takich samych kolorów albo trzech takich samych figur. W Kuku grać może nawet do kilkunastu osób. W Kuku można grać całą talią kart albo gdy w grze bierze udział mała liczba graczy można grać kartami od 9. Rozdający daje każdemu z graczy po trzy karty, zaś graczowi siedzącemu po swojej lewej stronie cztery. Gracz który ma cztery karty oddaje jedną kartę z nie pasujących mu kart graczowi który siedzi z lewej strony. Karty oddaje się zgodnie z ruchem wskazówek zegara. W przypadku powrotu do tej samej osoby i grające osoby potwierdzą taką możliwość wówczas gracz może zamienić kartę na jedną kartę z tali. Jeśli osoba która zbierze trzy jednakowe kolory lub figury nie krzyknie "kuku", a reszta graczy krzyknie wówczas osoba ta przegrywa. W sytuacji gdy wszyscy gracze poza jednym mają zebrane „kuku” wówczas gra się kończy a przegrany gracz musi odgadnąć „kuku” innych graczy może pomóc sobie jedynie własnymi kartami."</span></i><br />
<div style="font-family: Verdana,sans-serif;">
<br /></div>
<div style="font-family: Verdana,sans-serif;">
Spróbujemy zrobić system, który pozwoli nam na zagranie w nią
zarówno w "okienkach", stronie internetowej jak i telefonie komórkowym. Jest to na tyle prosta gra, że nie będzie trzeba za dużo męczyć się z oprogramowaniem jej logiki a na tyle trudna, że będę mógł traktować nasze rozważania jako punkt wyjściowy dla kolejnych artykułów (dodatkowo uprościmy sprawę i darujemy sobie zgadywanie na koniec gry, po prostu pierwszy gracz, który skompletuje kuku wygrywa).<br />
<br />
<span style="font-size: large;">Przykład</span></div>
<br />
<span style="font-family: Verdana,sans-serif;">Przed uruchomieniem Visual Studio polecam zainstalowanie sobie:</span><br />
<span style="font-family: Verdana,sans-serif;">- <a href="http://www.microsoft.com/download/en/details.aspx?id=23691">Visual Studio 2010 Service Pack 1</a> </span><br />
<span style="font-family: Verdana,sans-serif;">- <a href="http://www.microsoft.com/download/en/details.aspx?id=7335">Silverlight 4 SDK</a> (może być też 5)</span><br />
<span style="font-family: Verdana,sans-serif;">- <a href="http://www.microsoft.com/download/en/details.aspx?id=27570">Windows Phone SDK 1</a></span><br />
<span style="font-family: Verdana,sans-serif;">Gdy wszystko będzie już poinstalowane, skonfigurowane i dopięte na ostatni guziczek zapraszam do uruchomienia Visual Studio i utworzenia pustej solucji.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-DMh_aYANw0k/Ty1942d_f-I/AAAAAAAAASQ/E9VknSE_XZw/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="290" src="http://4.bp.blogspot.com/-DMh_aYANw0k/Ty1942d_f-I/AAAAAAAAASQ/E9VknSE_XZw/s400/01.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Następnie w nowej solucji utwórzmy dwa katalogi:</span><br />
<span style="font-family: Verdana,sans-serif;">- Shared - na projekty ze wspólnymi klasami</span><br />
<span style="font-family: Verdana,sans-serif;">- Client - na projekty klienckie </span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-CGsSPwBnA6U/Ty1-qpuU4bI/AAAAAAAAASY/1rXcY7wjZ1k/s1600/02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="275" src="http://4.bp.blogspot.com/-CGsSPwBnA6U/Ty1-qpuU4bI/AAAAAAAAASY/1rXcY7wjZ1k/s400/02.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Do katalogu Client dodajmy projekty klienckie:</span><br />
<span style="font-family: Verdana,sans-serif;">- WPF</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-VsJGahxAuso/Ty2AubpPP5I/AAAAAAAAASg/6JKXgP_8u2c/s1600/03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="243" src="http://3.bp.blogspot.com/-VsJGahxAuso/Ty2AubpPP5I/AAAAAAAAASg/6JKXgP_8u2c/s400/03.png" width="400" /></a></div>
<br />
<span style="font-family: Verdana,sans-serif;">- Silverlight</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-JU-WhSQYUKs/Ty2BWB466gI/AAAAAAAAASo/S8N6Hcu6uO0/s1600/04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="http://3.bp.blogspot.com/-JU-WhSQYUKs/Ty2BWB466gI/AAAAAAAAASo/S8N6Hcu6uO0/s400/04.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"> wraz z projektem hostującym na stronie www</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-eP1NYUupBcE/Ty2Byxsq0yI/AAAAAAAAASw/RxYd3bUgtTQ/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="255" src="http://1.bp.blogspot.com/-eP1NYUupBcE/Ty2Byxsq0yI/AAAAAAAAASw/RxYd3bUgtTQ/s320/05.png" width="320" /></a></div>
<span style="font-family: Verdana,sans-serif;"></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">- Windows Phone</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-MdTSzDoM33c/Ty2G3wa08hI/AAAAAAAAAS4/ziUhVxEO_Fs/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="245" src="http://2.bp.blogspot.com/-MdTSzDoM33c/Ty2G3wa08hI/AAAAAAAAAS4/ziUhVxEO_Fs/s400/06.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Do katalogu dodajmy projekt biblioteki klas</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Aym2m7E_jkM/Ty2H-nFrTxI/AAAAAAAAATA/ux-fPZOYRHU/s1600/07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="http://1.bp.blogspot.com/-Aym2m7E_jkM/Ty2H-nFrTxI/AAAAAAAAATA/ux-fPZOYRHU/s400/07.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">W tym projekcie będą znajdowały się klasy odpowiadające za logikę gry, które będą wspólne dla projektów klienckich. Dodajemy zatem referencję do tego niego w projekcie WPF, następnie w Silverlight i Phone. </span><br />
<span style="font-family: Verdana,sans-serif;">Udało Wam się? Mnie nie. Przy próbie dodania referencji w projekcie Silverlightowym wyskakuje komunikat:</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-Pv8kFq01O8c/Ty2Jlm4tJBI/AAAAAAAAATI/WhBtHVJEZ8s/s1600/08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="312" src="http://2.bp.blogspot.com/-Pv8kFq01O8c/Ty2Jlm4tJBI/AAAAAAAAATI/WhBtHVJEZ8s/s400/08.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Podobny dostaniemy przy próbie dodania referencji do projektu Phone'owego. Zatem w jaki sposób można współdzielić pliki skoro nie możemy podpiąć projektu do wszystkich typów aplikacji klienckich?</span><br />
<span style="font-family: Verdana,sans-serif;">Rozwiązanie tego problemu nie jest ani eleganckie, ani najwygodniejsze, ale póki co jedyne rozsądne. Musimy utworzyć analogiczne projekty z klasami wspólnymi dla każdej z docelowych platform klienckich:</span><br />
<span style="font-family: Verdana,sans-serif;">- Silverlighta</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-dmop4juUA7c/Ty2Ml2_gklI/AAAAAAAAATQ/Buw6vkZ2UsY/s1600/09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="243" src="http://1.bp.blogspot.com/-dmop4juUA7c/Ty2Ml2_gklI/AAAAAAAAATQ/Buw6vkZ2UsY/s400/09.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">- Phone'a</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-rMQi-KZjJRY/Ty2MmShJePI/AAAAAAAAATU/CG9QOlZIYP4/s1600/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="http://2.bp.blogspot.com/-rMQi-KZjJRY/Ty2MmShJePI/AAAAAAAAATU/CG9QOlZIYP4/s400/10.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Po tym wszystkim struktura projektów powinna wyglądać następująco:</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-fGvWHPQI_S0/Ty2UNLbSqbI/AAAAAAAAATo/xCrWwzswlSA/s1600/12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-fGvWHPQI_S0/Ty2UNLbSqbI/AAAAAAAAATo/xCrWwzswlSA/s1600/12.png" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Będą one tak jakby kopiami tego co mamy w głównym projekcie ze wspólnymi klasami. Aby kopia była wierna musimy skopiować właściwości projektu i generowanej dllki. Otwórzmy informacje projektu wzorcowego:</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-a9fWjlW9dz0/Ty2PjMiEYVI/AAAAAAAAATg/wL-e3BK97h4/s1600/11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="196" src="http://2.bp.blogspot.com/-a9fWjlW9dz0/Ty2PjMiEYVI/AAAAAAAAATg/wL-e3BK97h4/s400/11.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Musimy przenieść informacje:</span><br />
<span style="font-family: Verdana,sans-serif;">- Assembly Name</span><br />
<span style="font-family: Verdana,sans-serif;">- Default Namespace</span><br />
<span style="font-family: Verdana,sans-serif;">- Assembly Information</span><br />
<span style="font-family: Verdana,sans-serif;">Robimy to poprzez otworzenie właściwości projektów dla Silverlight oraz Phone i zmianę odpowiednich pól a na koniec zapisanie plików projektów.</span><br />
<span style="font-family: Verdana,sans-serif;">Dzięki temu uzyskamy, to że generowane pliki będą miały ten sam namespace oraz takie same właściwości asemblatu. Będziemy mogli dzielić bez problemu klasy poprzez serwisy wcf, serializować je itd.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Domyślam się, że teraz po Waszej głowie chodzi myśl: "Wszystko pięknie, ładnie, ale czy teraz będziemy musieli dodawać te same klasy do 3 różnych projektów i przy każdej zmianie uaktualniać w 3 miejscach?". Odpowiedzią jest: "I tak, I nie". </span><br />
<span style="font-family: Verdana,sans-serif;">Tak, będziemy musieli dodawać plik do każdego projektu osobno. Nie, wystarczy że będziemy zmieniać je w jednym miejscu. Jak to możliwe? Visual Studio umożliwia dodawanie plików do projektu jako linków. Dzięki tym linkom VS nie tworzy nowego pliku tylko odwołuje się do lokacji w innym miejscu. Do projektu wzorcowego dodawać będziemy pliki w normalny sposób, do pozostałych linki do nich.</span><br />
<span style="font-family: Verdana,sans-serif;">Aby pokazać jak to się robi utwórzmy interfejs IKukuGame w projekcie Multiplatform.Shared. Chcąc dodać plik jako link naciskamy na projekcie Multiplatform.Shared.Silverlight "Add Existing Item". Przechodzimy do lokalizacji gdzie znajduje się świeżo dodany interfejs. Zaznaczamy go i naciskamy małą strzałkę przy przycisku "Add". Pojawi nam się wtedy opcja "Add As Link". Naciskamy ją i et voilà!</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-XhuvtvCIXV0/Ty2WKrDlyjI/AAAAAAAAATw/AyKMFtinobk/s1600/13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="260" src="http://4.bp.blogspot.com/-XhuvtvCIXV0/Ty2WKrDlyjI/AAAAAAAAATw/AyKMFtinobk/s400/13.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Kody źródłowe można pobrać <a href="http://joomanji.no-ip.org/blog/multiplatform.zip">tutaj</a>.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif; font-size: large;">Podsumowanie</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Po tym artykule powinniście już wiedzieć, że:</span><br />
<span style="font-family: Verdana,sans-serif;">- zwykły .NET, Silverlight i Phone to nie to samo, </span><br />
<span style="font-family: Verdana,sans-serif;">- nie da się w prosty sposób połączyć ze sobą projektów,</span><br />
<span style="font-family: Verdana,sans-serif;">- ale da się w nieco trudniejszy,</span><br />
<span style="font-family: Verdana,sans-serif;">- powinniście znać zasady gry w Kuku.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;">W kolejnym wpisie podążymy tropem tego ostatniego punktu i zrobimy kolejny krok w stronę utworzenia gry multiplayer w Kuku.</span></div>
</div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-85937371287919089562011-12-10T21:48:00.001+01:002011-12-10T21:48:36.408+01:00Scrum i Team Foundation Server cz.6 - Proces TDD<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="font-family: Verdana,sans-serif; text-align: justify;">
W kilku ostatnich wpisach przedstawiłem czym jest metodyka Scrum, po co i jak ją stosować przy użyciu Team Foundation Server. W teorii moglibyśmy już rozpocząć projekt i z powodzeniem go prowadzić. Możliwe, że więcej wiedzy nie było by Wam szybko potrzebne, ale podejrzewam, że całkiem szybko zaczęły się pojawiać pytania o zarządzanie i przepływ zadań, np.:<br />
- Który rodzaj zadania jest z czym powiązany?<br />
- Czy jak dodamy buga to mamy dodać do niego też taska? <br />
- do czego służy test case a do czego impediment?<br />
- itd. Itp.</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
Takie pytania są nieuchronne, każdy Scrum Master będzie musiał je wysłuchiwać po 100 razy. Można jednak ich częstotliwość zmniejszyć poprzez spisanie dokumentu, zawierającego przykładowy przepływ pomiędzy zadaniami oraz zasady tworzenia dokumentów. Dzięki niemu będziemy mogli w krytycznej sytuacji bez większych wyrzutów sumienia odpowiedzieć „zajrzyj sobie do dokumentacji”.</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br />
W Scrum centralnym elementem opisu biznesowego przypadku jest Historia Użytkownika (User Story) zwana również „elementem rejestru produktu” (Product Backlog Item – PBI). Opisuje ona wartość biznesową, która ma zostać dodana do projektu np. ”<b>Jako</b> użytkownik gry One Card Master <b>chcę</b>,
zobaczyć informację o aktualnej liście uczestników gry, <b>abym</b>
wiedział z kim gram”.<br />
Schemat można było by opisać (tak jak przedstawiono we <a href="http://premium-hands.blogspot.com/2011/12/tdd-cz1.html" target="_blank">wpisie</a>) przez:</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<b>JAKO </b><Osoba, rola> <br />
<b>CHCĘ </b><Funkcjonalność, czynność><br />
<b>ABY </b><Uzasadnienie biznesowe></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
W teorii pisanie historii użytkownika wydaje się sprawą zupełnie prostą, ale w praktyce okazuje się, że jest zupełnie inaczej. Same zasady tworzenia historii użytkownika są materiałem na osobny wpis.<br />
No ale wracając do tematu procesu. Tak jak wspomniałem we <a href="http://oskar-at-net.blogspot.com/2011/11/scrum-i-team-foundation-system-cz1.html" target="_blank">wpisie</a> Scrum jest mocno powiązany z metodyką TDD. Podążając z jej zasadami, będzie nam dużo łatwiej prowadzić projekt, oraz zarządzać przepływem. We wspomnianym wpisie powiedziałem, że każdy PBI powinien mieć wyraźnie i dokładnie opisane kryteria akceptacji – czyli warunki, które muszą zostać spełnione, żeby zadanie zostało zaakceptowane.</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br />
Same historie użytkownika opisują jedynie ogólne aspekty realizacji biznesowego problemu. Aby kompleksowo zamodelować proces wytwarzania funkcjonalności konieczne jest dodanie do nich konkretnych elementów tj:</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://consultingblogs.emc.com/blogs/crispinparker/FeatureTrackingWorkItems_246F141A.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="http://consultingblogs.emc.com/blogs/crispinparker/FeatureTrackingWorkItems_246F141A.png" width="311" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Źródło: <a href="http://consultingblogs.emc.com/crispinparker/archive/2010/05/18/getting-started-with-scrum-for-team-system-version-3-tfs-2010.aspx" target="_blank">Crispin Parker's Blog</a></td></tr>
</tbody></table>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br />
- <b>Task </b>– relacja „Implemented-By” – czyli opisuje wszystko to co jest konieczne do tego, żeby od strony programistycznej zaimplementować historię użytkownika<br />
- <b>Acceptance Test</b> – relacja „Tested-By” – opisuje testy akceptacyjne, czyli to w jaki sposób historia użytkownika będzie testowana<br />
- <b>Bug Report</b> – relacja „Failed – By” – opisuje co poszło nie tak przy testach akceptacyjnych<br />
- <b>Impediment</b> – relacja „Impeded-By” – przeszkoda, Opisuje problemy, które wystąpiły przy implementacji historii użytkownika, może to być np. sytuacja, że przy tworzeniu algorytmu nie wzięliśmy pod uwagę jakiegoś aspektu, którego zaimplementowanie wymaga dodatkowej analizy</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br />
Co z sytuacjami gdy odnajdziemy inne błędy, które nie zostały ujęte w testy akceptacji? Dorzucamy do rejestru produktu (ewentualnie rejestru spritu jeżeli jest on kluczowy dla jego oddania) element typu <b>Bug</b>. Ma on identyczną strukturę zależności jak historia użytkownika. Powinien również posiadać zadanie, opis testów, które będą dokonywane przy weryfikacji tego buga, może zawierać Impediment oraz raport o błędzie, który mówi o tym, że rozwiązanie błędu nie zostało zaakceptowane.</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br />
Paczkę koniecznej wiedzy teoretycznej już uzyskaliśmy, możemy teraz przejść do przykładu. Będzie on pokazany na Team Foundation Server 11 DP oraz Visual Studio 11 DP. Załóżmy, że tworzymy znaną z innych wpisów grę One Card Master. Mamy już zaimplementowaną część kodu odpowiadającego za zarządzanie graczami. Dostępne już są klasy:<br />
<br />
- informacje o graczu:<br />
<br /></div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public class Player
{
public string Name { get; set; }
}
</pre>
<br />
<div style="font-family: Verdana,sans-serif;">
- zarządzajanie graczami, pozwalające na ich dodawanie</div>
<div style="font-family: Verdana,sans-serif;">
<br /></div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public interface IPlayersManager
{
IList<Player> GetPlayers();
void AddPlayer(Player player);
}
public class PlayersManager : IPlayersManager
{
private readonly IList<Player> _playersList = new Listt<Player>();
public void AddPlayer(Player player)
{
_playersList.Add(player);
}
public IList<Player> GetPlayers()
{
return _playersList;
}
}
</pre>
<div style="font-family: Verdana,sans-serif;">
<br />
- dostępne są również klasy pozwalające na drukowanie informacji na ekranie</div>
<div style="font-family: Verdana,sans-serif;">
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public interface IPrinter
{
void Print(string text);
}
public class ConsolePrinter : IPrinter
{
public void Print(string text)
{
Console.WriteLine(text);
}
}
</pre>
<br />
<div style="text-align: justify;">
Klient zażyczył sobie, że musimy dodać funkcjonalność wyświetlania aktualnej listę graczy. </div>
<div style="text-align: justify;">
Załóżmy, że znajdujemy się na etapie planowania sprintu. Pierwszym krokiem, który powinniśmy zrobić jest dodanie nowej historii użytkownika. Dokonujemy tego poprzez kliknięcie menu jak na poniższym obrazku.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-y3rspI-nlRA/TtvyAwJ8QlI/AAAAAAAAAQY/AG8zfTbzhuI/s1600/03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="http://2.bp.blogspot.com/-y3rspI-nlRA/TtvyAwJ8QlI/AAAAAAAAAQY/AG8zfTbzhuI/s400/03.png" width="400" /></a></div>
<div style="text-align: justify;">
<br />
<b>Historia użytkownika</b><br />
<br /></div>
<div style="text-align: justify;">
Ukaże nam się okno definicji historii użytkownika:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-WwjFAdgYSkk/Ttv46xziliI/AAAAAAAAAQw/bsBET6qqtFs/s1600/04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="237" src="http://4.bp.blogspot.com/-WwjFAdgYSkk/Ttv46xziliI/AAAAAAAAAQw/bsBET6qqtFs/s400/04.png" width="400" /></a></div>
<div style="text-align: justify;">
<br />
Nazywamy naszą historię użytkownika "Wyświetlanie aktualnej listy graczy" podajemy jego opis:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
”<b>Jako</b> użytkownik gry One Card Master <b>chcę</b>,
zobaczyć informację o aktualnej liście uczestników gry, <b>abym</b>
wiedział z kim gram”</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Podajemy kryteria akceptacji:</div>
<div style="text-align: justify;">
<br /></div>
1. Po dołączeniu nowego gracza system powinien wyświetlić zaktualizowaną
listę użytkowników.<br />
2. W obecnej wersji powinien wyświetlać informacje na konsoli.<br />
3. Informacja o użytkowniku powinna być zapisana w formacie "{Lp}. Nazwa:
{Nazwa}". <br />
<div style="text-align: justify;">
<br />
<b>Przypadek testowy</b><br />
<br /></div>
<div style="text-align: justify;">
Zapisujemy historię użytkownika, ale nie zamykamy okna tylko przechodzimy do zakładki "Test cases" i naciskamy przycisk "New".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-zcaSIrjPAsA/Tt-5XNext3I/AAAAAAAAAQ4/c66y99A2rMo/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="http://3.bp.blogspot.com/-zcaSIrjPAsA/Tt-5XNext3I/AAAAAAAAAQ4/c66y99A2rMo/s400/05.png" width="400" /></a></div>
<br />
Dodajemy w ten sposób test akceptacji. Nazywamy go "Test wyświetlania aktualnej listy graczy" i naciskamy "OK". Otworzy się nam widok przypadku testowego. Zapisujemy go. Dostaniemy teraz pełen dostęp do opcji tworzenia testu historii użytkownika.<br />
Jak łatwo zauważyć cały czas postępujemy tutaj zgodnie z metodyką TDD:<br />
- najpierw opisaliśmy co chcemy (historia użytkownika),<br />
- następnie co musi być spełnione, żeby uznać funkcjonalność za poprawnie działającą (kryteria akceptacji),<br />
- teraz napiszemy jak będziemy to testować.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-q5FdAxtDqN4/Tt--aptqc-I/AAAAAAAAARA/fq09xjKv4r8/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="http://4.bp.blogspot.com/-q5FdAxtDqN4/Tt--aptqc-I/AAAAAAAAARA/fq09xjKv4r8/s400/06.png" width="400" /></a></div>
<br />
Naciskamy przycisk "Edit with Microsoft Test Manager". Po tej akcji przejdziemy do zewnętrznego programu przygotowanego przez Microsoft specjalnie do planowania, zarządzania oraz przeprowadzania testów (postaram się go przedstawić w osobnym wpisie). Nie wgłębiając się specjalnie w szczegóły - posłuży on nam do zdefiniowania kroków naszego testu.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-vgxMCTfUuBE/Tt_DuyuGaXI/AAAAAAAAARI/dw5u7A-4oZM/s1600/07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="272" src="http://1.bp.blogspot.com/-vgxMCTfUuBE/Tt_DuyuGaXI/AAAAAAAAARI/dw5u7A-4oZM/s400/07.png" width="400" /></a></div>
<br />
Dodajemy trzy kroki (poprzez uzupełnienie odpowiednich pól w tabelce "Steps"):<br />
<br />
"1. Dodajemy gracza "Jan Kowalski" poprzez metodę AddPlayer klasy PlayersManager - Wyświetlona informacja: "01. Nazwa: Jan Kowalski"<br />
2. Dodajemy gracza "Krzysztof Krawczyk" poprzez metodę AddPlayer klasy PlayersManager - Wyświetlone informacje: "01. Nazwa: Jan Kowalski", "02. Nazwa: Krzysztof Krawczyk"<br />
3. Dodajemy gracza "Eustachy Janicki" poprzez metodę AddPlayer klasy PlayersManager - Wyświetlone informacje: "01. Nazwa: Jan Kowalski", "02. Nazwa: Krzysztof Krawczyk", "03. Eustachy Janicki" "<br />
<br />
Przechodzimy do zakładki Summary i przeklejamy tam tekst z kryteriów akceptacji, zapisujemy zmiany i zamykamy Test Managera. Po odświeżeniu widoku Test Case'a powinny pojawić się na nim wpisane przez nas dane.<br />
<br />
<b>Zadanie</b><br />
<br />
Wracamy ponownie do naszej historii użytkownika. Dodamy teraz zadanie developerskie poprzez przejście do zakładki Tasks i naciśnięcie przycisku "New". Nazywamy go "Implementacja wyświetlania aktualnej listy graczy".<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Xc8KPjCttOU/Tt_JYD8DpkI/AAAAAAAAARQ/JW1ZN2PTW40/s1600/08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/-Xc8KPjCttOU/Tt_JYD8DpkI/AAAAAAAAARQ/JW1ZN2PTW40/s400/08.png" width="400" /></a></div>
<br />
Wypełniamy pola zgodnie z powyższym obrazkiem (opis jako: "Należy stworzyć taki mechanizm, który po dodaniu gracza poprzez metodę AddPlayer
z klasy PlayerManager automatycznie wyświetli na ekranie aktualną listę graczy.") i przypisujemy go do osoby, która będzie go realizowała (np. do siebie) poprzez "Assigned To".<br />
Gdy zaczniemy realizację zadania ustawiamy jego status (State) na "In Progress", oraz status PBI na "Approved".<br />
<br />
<b>Przeszkoda</b><br />
<br />
Załóżmy, że okazało się, że nie wiemy jak coś zrobić. Specyfikacja jest niedokładna, mamy problem z wymyśleniem odpowiedniego rozwiązania, albo problemy techniczne z komputerem. <br />
<br />
Załóżmy, że nie mamy pojęcia jak ugryź kompletnie to zadanie, musimy przeprowadzić konsultacje. Przechodzimy wtedy do naszej historii użytkownika, do zakładki "Links" i naciskamy przycisk "New".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-9tkLVRBQmjc/Tt_ZSoGyF_I/AAAAAAAAARg/pGiTCaMC5hA/s1600/09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="http://1.bp.blogspot.com/-9tkLVRBQmjc/Tt_ZSoGyF_I/AAAAAAAAARg/pGiTCaMC5hA/s400/09.png" width="400" /></a></div>
<br />
Uzupełniamy "Link Type" jako "Child" (bo Impediment będzie dzieckiem naszej historii użytkownika) oraz "Work Item Type" jako Impediment. Nazywamy go "Problem z metodą automatycznego wyświetlania aktualnej listy graczy" i naciskamy OK.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-kH9OgsJRKNo/Tt_aMtAn7HI/AAAAAAAAARo/AcpNLgzq-S8/s1600/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="http://3.bp.blogspot.com/-kH9OgsJRKNo/Tt_aMtAn7HI/AAAAAAAAARo/AcpNLgzq-S8/s400/10.png" width="400" /></a></div>
<br />
Pojawi się widok Impedimentu, dopisujemy opis (np. "Mam problem z wymyśleniem metody automatycznego wyświetlania aktualnej listy
graczy, potrzebuję konsultacji z kimś bardziej doświadczonym."). Zapisujemy go i wracamy do widoku PBI. Musimy na nim zaznaczyć, że prace nad nim zostały wstrzymane. Dokonujemy tego poprzez oznaczenie jego pola "Blocked" na "Yes".<br />
<br />
Załóżmy, że udało nam się ustalić, że powinniśmy rozwiązać problem <br />
automatycznego wyświetlania listy gracz przy pomocy wzorca obserwatora. Przechodzimy do utworzonej wcześniej Przeszkody, wpisujemy nasze rozwiązanie w zakładkę "Resolution" i zmieniamy status na zamknięty ("Closed").<br />
<br />
Możemy teraz przystąpić do programowania.<br />
<br />
<b>Implementacja</b><br />
<br />
Implementację zaczynamy oczywiście od napisania testu akceptacyjnego (przykład będzie mocno uproszczony bo nie o to tutaj chodzi - więcej na temat testów jednostkowych możecie znaleźć we wpisach tutaj i tu). Postępujemy zgodnie z tym co zawarliśmy w testach akceptacyjnych oraz Impedimencie. Opis wzorca obserwator można znaleźć przykładowo <a href="http://www.dofactory.com/Patterns/PatternObserver.aspx" target="_blank">tutaj</a>.<br />
Test może wyglądać następująco:<br />
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">[TestMethod]
public void AddPlayersPrintValidInformations()
{
var mocks = new MockRepository();
var playersManagers = new PlayersManager();
var printer = mocks.StrictMock<Player>();
var playersObserver = new PlayersObserver(printer);
playersObserver.Observe(playersManagers);
playersManagers.Attach(playersObserver);
//Dodanie pierwszego gracza
Expect.Call(()=> printer.Print("1: Jan Kowalski"));
//Dodanie drugiego gracza
Expect.Call(() => printer.Print("1: Jan Kowalski"));
Expect.Call(() => printer.Print("2: Krzysztof Krawczyk"));
//Dodanie trzeciego gracza
Expect.Call(() => printer.Print("1: Jan Kowalski"));
Expect.Call(() => printer.Print("2: Krzysztof Krawczyk"));
Expect.Call(() => printer.Print("3: Eustachy Janicki"));
mocks.ReplayAll();
//Dodanie pierwszego gracza
playersManagers.AddPlayer(new Player { Name = "Jan Kowalski" });
//Dodanie drugiego gracza
playersManagers.AddPlayer(new Player { Name = "Krzysztof Krawczyk" });
//Dodanie trzeciego gracza
playersManagers.AddPlayer(new Player { Name = "Eustachy Janicki" });
mocks.VerifyAll();
}
</pre>
<br />
Oczywiście przy pisząc test postępujemy zgodnie z metodologią TDD, po kolei uzupełniając definicje klas i metod. Przykładowa ich implementacja mogła by wyglądać:<br />
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public class PlayersObserver : IPlayersObserver
{
private readonly IPrinter _printer;
private IPlayersManager _playersManager;
public PlayersObserver(IPrinter printer)
{
_printer = printer;
}
public void Observe(IPlayersManager playersManager)
{
_playersManager = playersManager;
}
public void Update()
{
var players = _playersManager.GetPlayers();
var i = 0;
foreach (var player in players)
{
_printer.Print(
String.Format(
"{0}: {1}", ++i, player.Name));
}
}
public void OnPrintState(string info)
{
Console.WriteLine(info);
}
}
public class PlayersManager : IPlayersManager
{
private readonly IList<IPlayersObserver> _observers
= new List<IPlayersObserver>();
private readonly IList<Player> _playersList = new List<Player>();
public void Attach(IPlayersObserver observer)
{
_observers.Add(observer);
}
public void Detach(IPlayersObserver observer)
{
_observers.Remove(observer);
}
public void AddPlayer(Player player)
{
_playersList.Add(player);
foreach(var observer in _observers)
{
observer.Update();
}
}
public IList<Player> GetPlayers()
{
return _playersList;
}
}
</pre>
<br />
W tym momencie kończy się proces implementacji. Nasze testy przechodzą. Możemy zrobić Check in naszych zmian. Przechodzimy do Team Explorera, naciskamy "Pending Changes".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-CTVASZ_Nn2Y/TuOv33B1-RI/AAAAAAAAARw/EqOZ0HnnQ6g/s1600/13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://1.bp.blogspot.com/-CTVASZ_Nn2Y/TuOv33B1-RI/AAAAAAAAARw/EqOZ0HnnQ6g/s320/13.png" width="306" /></a></div>
<br />
Pierwszą rzeczą jest dodanie komentarza (nie zapominajmy do tym!). Kolejną powiązanie naszych zmian z zadaniami. Naciskamy "Add Work Item by ID" i dodajemy zarówno nasze zadanie jak i PBI. Przy wiązaniu zmian mamy dwie opcje:<br />
- <b>Associate </b>- po prostu "doklejamy" informację o tym, że zmiana dotyczy danego Work Itema (WI)<br />
- <b>Resolve </b>- robi to samo co Associate i dodatkowo zmienia status WI na rozwiązany<br />
Ponieważ uznajemy nasze zadanie za skończone zaznaczamy je jako Resolve. Decyzję o zakończeniu historii użytkownika zgodnie z metodyką Scrum podejmuje Właściciel Produktu, dlatego też w przypadku PBI zaznaczamy tylko Associate.<br />
Gdy nasze zmiany wejdą z sukcesem pozostaje nam tylko jedna rzecz do zrobienia - podpięcie naszego testu akceptacyjnego do zdefiniowanego Test Case'a. Otwieramy informacje o nim i przechodzimy do zakładki "Associated automation".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-sqa7xI26m2o/TuO5Q2E6eKI/AAAAAAAAASA/94f9VW_iNWs/s1600/14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="http://1.bp.blogspot.com/-sqa7xI26m2o/TuO5Q2E6eKI/AAAAAAAAASA/94f9VW_iNWs/s400/14.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-LoznhFO0Erw/TuO5G0WDPBI/AAAAAAAAAR4/X8UwNfbKMxM/s1600/14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
Wybieramy nasz test jednostkowy poprzez przycisk koło pola "Automated test name".<br />
Poprawiamy wartość effort przy zadaniu oraz PBI i jeżeli wszystko zrobiliśmy poprawnie zakończyliśmy tym samym nasz proces implementacji.<br />
<br />
<b>Testy</b><br />
<br />
Po zakończeniu implementacji (zwykle na koniec Sprintu) Właściciel Produktu testuje czy wszystkie historie użytkownika zostały zrealizowane poprawnie. <br />
W naszym przypadku okazuje się, że wystąpił błąd. W opisie testu akceptacji było napisane, że:<br />
<br />
"Dodajemy gracza "Jan Kowalski" poprzez metodę AddPlayer klasy PlayersManager - Wyświetlona informacja: "01. Nazwa: Jan Kowalski"<br />
<br />
My w trakcie implementacji nie zauważyliśmy, że numery mniejsze od 10 mają mieć zero na początku. Proces zgłaszania i rozwiązania wygląda następująco:<br />
1. Właściciel produktu dodaje teraz błąd powiązany z naszą historią użytkownika (w sposób analogiczny jak podpinaliśmy impediment).<br />
2. My, po analizie błędu oceniamy ile czasu zajmie jego poprawienie, uaktualniamy effort dla PBI oraz buga<br />
3. Dodajemy zadanie-dziecko do błędu (analogicznie jak zadanie do historii użytkownika)<br />
4. Gdy rozwiążemy błąd i wrzucamy nasze zmiany spinamy je zarówno z zadaniem,błędem jak i historią użytkownika.<br />
5. Gdy Właściciel Produktu zaakceptuje rozwiązanie zamyka błąd i oznacza historię użytkownika za zrealizowaną.<br />
<br />
<b>Podsumowanie</b><br />
<br />
Mam nieodparte wrażenie, że ten artykuł jest z jednej strony za krótki, z drugiej, że za długi. Dlaczego? Za krótki gdyż temat jest tak rozległy, że można by było napisać książkę i to by było mało. Za długi, bo nie wiem czy ilość szczegółów nie zamaże obrazu całości.<br />
Mam jednak nadzieję, że udało mi się jednak przekazać ideę oraz że lektura mojego artykułu pozwoli Wam zrozumieć jak można zamodelować proces tworzenia funkcjonalności w TFS zgodnie z TDD i metodyką Scrum.</div>
</div>
</div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-35634245429446895722011-11-30T22:05:00.001+01:002011-12-03T21:04:49.484+01:00Scrum i Team Foundation Server cz.5 - Continuous Integration<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">1. Trochę teorii</span></b></span><br />
<br />
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Każdy z nas w trakcie zawodowej kariery miał (nie)przyjemność pracować z systemami kontroli wersji. Codziennie w trakcie swojej pracy wrzucamy, pobieramy z nich pliki, rozwiązujemy konflikty. Wiemy po co je używać, ale czy wiemy jak? Tak jak w każdej dziedzinie życia pewne rzeczy można robić lepiej lub gorzej.<span style="background-color: yellow;"></span> W tym artykule postaram się pokazać kilka dobrych zasad ciągłej integracji (Continuous Integration), które pozwolą usprawnić trochę ten proces. Na koniec przedstawię przykład jak wdrożyć te zasady w Team Foundation Server.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Systemy kontroli wersji są czymś o czym powinniśmy po<span style="background-color: white;">myśleć na samym początku projektu</span>. Mają wiele zalet, nie można się bez nich obyć, "ale...". Tym "ale" jest najbardziej zawodny element procesu - ludzie. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Każdy z nas nie raz klął na kolegę, który wrzucił niebudujący się kod do repozytorium, drżał przed nadchodzącymi konfliktami przy pobraniu nowej wersji repozytorium. Myślę, że każdy z nas mógłby wymienić z imion współpracowników specjalizujących się we wrzucaniu niebudującego się kodu. </span></div>
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.diaryofaninja.com/asset/blogimages/image_d2c5590a-0a26-47ee-acad-edb2ef42521e.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://www.diaryofaninja.com/asset/blogimages/image_d2c5590a-0a26-47ee-acad-edb2ef42521e.png" /></a></div>
</div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Na bazie swoich doświadczeń uważam, że sporo z tych błędów można wyeliminować poprzez stosowanie się do kilku prostych zasad:</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><b>1. W repozytorium znajduje się tylko kompilujący się kod</b> - przed wrzuceniem swoich zmian, poświęćmy czas i przebudujmy chociaż projekt. Nie ma nic bardziej irytującego niż niebudujący się kod. Nieszczęśliwcowi, który ściągnie rewizję w takiej sytuacji zwykle pozostaje cofnięcie się do poprzedniej działającej wersji, lub zrobienie hacku.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><b>2. W repozytorium znajduje się tylko działający kod</b> - jest to rozwinięcie pierwszej zasady. Sam fakt, że kod się buduje nie oznacza, że działa poprawnie. Przed wrzuceniem wersji poświęćmy chwilę na sprawdzenie czy nasz kod działa poprawnie: odpalmy testy, przeklikajmy się przez modyfikowane moduły. Często wydaje nam się to stratą czasu, bo "przecież to była tylko mała zmiana", a potem okazuje się, że zmianę zrobiliśmy na szybko i wrzuciliśmy kod, który wywala pół aplikacji. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Oczywiście, niektórzy powiedzą, że czasami nie da się tego zrobić, gdy więcej niż jedna osoba pracuje nad tym samym kodem i muszą się nim dzielić. Repozytoria kodu mają mechanizmy pozwalające na rozwiązanie tych problemów: tworzenie osobnych gałęzi kodu (branch), odkładanie kodu na półki (shelve). Jeżeli zastosowanie tych rozwiązań jest zbyt kłopotliwe - zróbmy wszystko by okres "zepsutego" repozytorium trwał najkrócej.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><b>3. </b><b>Wrzucajmy regularnie i często nasze zmiany</b> - oczywiście musimy zachować pierwsze dwie zasady. Dzielmy nasz kod na małe fragmenty (units of code). Oprócz takich zysków jak lepsza jakość kodu, zmniejszamy szansę na kłopotliwe rozwiązywanie złożonych konfliktów.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><b>4. Im częściej robimy update - tym lepiej</b> - jest to szczególnie kluczowe, gdy robimy dużą zmianę, mającą duży wpływ na działanie systemu. </span><span style="font-family: Verdana,sans-serif;">Musimy przeprowadzić dużo testów, n</span><span style="font-family: Verdana,sans-serif;">ie możemy wtedy szybko wrzucić zmian. Im częściej będziemy pobierać zmiany tym szybciej połączymy się z kodem innych i szansa na konflikty zdecydowanie zmaleje.</span></div>
<div style="text-align: justify;">
<b><span style="font-family: Verdana,sans-serif;"><br /></span></b></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><b>5. Piszmy komentarze gdy wrzucamy kod</b> - niby drobna rzecz, ale bardzo pomaga gdy musimy znaleźć przyczynę modyfikacji fragmentu kodu. Napiszmy z jakim zadaniem nasze zmiany są związane, co zmodyfikowaliśmy, dodaliśmy, usunęliśmy tym lepiej. Krótko ale treściwie.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Niestety teoria teorią, a praktyka praktyką. Często okazuje się, że sporo ludzi podchodzi do nich nonszalancko. Czasami skomplikowanie systemu nie pozwala w prosty i szybki sposób na sprawdzenie wpływu naszych zmian na jego działanie.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Z pomocą przychodzą nam zasady i systemy Continuous Integration. Oprócz zasad dobrego używania kodu (m.in. tych, które wymieniłem powyżej) główną ideą jest to, że zmiany w kodzie powinny być ciągle integrowane ze sobą. Powinna być regularnie sprawdzana jego spójność, integralność oraz poprawność działania. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Dokonuje się tego przez regularne buildy projektu, uruchamianie testów itd. Powinny się one odbywać w środowisku identycznym do docelowego klienckiego (eliminujemy w ten sposób błędy wynikające z tego, że programiści mają różne konfiguracje swoich systemów). Każda zmiana powinna zostać przetestowana. Jeżeli nie spełni kryteriów akceptacji to powinna nie zostać dopuszczona do repozytorium, lub zespół projektowy powinien zostać niezwłocznie powiadomiony o pojawieniu się błędnego kodu.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Postaram się pokazać jak te cele można osiągnąć przy pomocy Team Foundation Server. Pokażę jak utworzyć dwie definicje buildów, które powinny rozwiązać większość podstawowych problemów:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <b>build dzienny</b> - będzie raz na dobę sprawdzał czy projekt buduje się, czy wszystkie testy przechodzą. Ponieważ może on trwać długo, uruchamiany będzie w nocy - by nie utrudniać pracy programistom.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <b>build wejśćiowy (gated build)</b> - będzie sprawdzał czy kod wrzucany jest poprawny. Jeżeli nie spełni zadanych kryteriów, nie dostanie się do repozytorium. Jakie warunki będziemy sprawdzać? Pierwszym będzie kompilacja projektu, drugim przejście najważniejszych testów (uruchamianie wszystkich nie było by dobrym posunięciem, bo trwało by zdecydowanie za długo).</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;"><b>2. Trochę praktyki</b></span></span><br />
<span style="font-family: Verdana,sans-serif;"> </span><br />
<div style="text-align: justify;">
<br />
<span style="font-family: Verdana,sans-serif;">Pierwszym krokiem jest utworzenie projektu i dorzucenie go do Team Foundation Server. Bazował będę na przykładzie opisanym w <a href="http://oskar-at-net.blogspot.com/2011/11/scrum-i-team-foundation-server-cz4.html">"Scrum i Team Foundation Server cz.4 - Tworzymy projekt"</a>.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Pierwszą czynnością jest utworzenie folderu, do którego będą wrzucane DLLki budowanych solucji. Na nim będzie działał serwer. Załóżmy folder na dysku C: o nazwie "BuildFolder". Konieczne jest nadanie maksymalnych uprawnień do folderu procesowi buildów TFS (dla mnie będzie to "Local Service"). Oprócz tego musimy udostępnić w sieci lokalnej ten folder.</span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-wVKYbFM7mg8/TtaJw4WovEI/AAAAAAAAAOw/YBf5n1uYYH8/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="281" src="http://1.bp.blogspot.com/-wVKYbFM7mg8/TtaJw4WovEI/AAAAAAAAAOw/YBf5n1uYYH8/s400/01.png" width="400" /></a></div>
<br />
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Mając już skonfigurowany folder możemy przejść do właściwej konfiguracji. Otwieramy Visual Studio i otwieramy Team Explorera (Menu => View => Team Explorer)</span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-NwpXH-8Ta-4/TtaQnJoFQwI/AAAAAAAAAO4/hj1tKdy0aJE/s1600/02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-NwpXH-8Ta-4/TtaQnJoFQwI/AAAAAAAAAO4/hj1tKdy0aJE/s1600/02.png" /></a></div>
<br />
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Przechodzimy do menu konfiguracji buildów naciskając przycisk "Builds". Aby dodać nową definicję naciskamy przycisk "New Build Definition". Dodajemy dwie definicje:</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><b>1. Build dzienny</b> </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">W pierwszym oknie wpisujemy jego nazwę (np. "OneCardMaster - Daily" i ustalamy, że ma być aktywny zaznaczając opcję "Enabled".</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"> </span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-tsjOliHbxvE/Tto5sHwUOOI/AAAAAAAAAPA/tVe5dUSlK2I/s1600/04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="368" src="http://3.bp.blogspot.com/-tsjOliHbxvE/Tto5sHwUOOI/AAAAAAAAAPA/tVe5dUSlK2I/s400/04.png" width="400" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"> </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"> Przechodzimy do zakładki "Trigger". </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-mmIUk1d2kq0/Tto6fB14TjI/AAAAAAAAAPI/63OIylFruGY/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="363" src="http://2.bp.blogspot.com/-mmIUk1d2kq0/Tto6fB14TjI/AAAAAAAAAPI/63OIylFruGY/s400/05.png" width="400" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br />W niej definiowane wyzwalacze dla naszego buildu. Chcemy, żeby uruchamiał się codziennie o godzinie 3 w nocy, nawet jeżeli kod nie zmienił się. Zaznaczamy opcje jak na obrazku powyżej. </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Przechodzimy do zakładki Build Defaults. I podajemy w niej adres sieciowy utworzonego przez nas wcześniej katalogu do buildów.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-cuWhHpaW_WE/Tto8hLTnGHI/AAAAAAAAAPQ/Ctll0y6morg/s1600/07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="365" src="http://3.bp.blogspot.com/-cuWhHpaW_WE/Tto8hLTnGHI/AAAAAAAAAPQ/Ctll0y6morg/s400/07.png" width="400" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">W zakładkach Workspace, Process i Retention Policy zostawiamy wartości domyślne.<br />Naciskamy przycisk zapisz i mamy skonfigurowany pierwszy build.</span><br />
<br />
<b><span style="font-family: Verdana,sans-serif;">2. Build wejściowy</span></b><br />
<br />
<span style="font-family: Verdana,sans-serif;"> </span><br />
<span style="font-family: Verdana,sans-serif;"> Tworzymy kolejną definicję builda poprzez Team Explorera. Podajemy jej nazwę "One Card Master - Gated". Zakładki Workspace, Build Defaults, Retention Policy tak samo jak w przypadku builda dziennego.</span><br />
<span style="font-family: Verdana,sans-serif;">Przechodzimy do zakładki Trigger i ustalamy w niej opcję "Gated Check-in".</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-81WrrZAK-TY/TtpaiWXZO0I/AAAAAAAAAPY/AIANK1p-CbE/s1600/09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="362" src="http://3.bp.blogspot.com/-81WrrZAK-TY/TtpaiWXZO0I/AAAAAAAAAPY/AIANK1p-CbE/s400/09.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Następnie naciskamy w Process. Rozwijamy kolejno sekcje: Basic, Automated Tests, Test Assembly.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-w2OALDVDTVY/TtpbRcspFXI/AAAAAAAAAPg/ZWNsmi_h8bg/s1600/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="365" src="http://3.bp.blogspot.com/-w2OALDVDTVY/TtpbRcspFXI/AAAAAAAAAPg/ZWNsmi_h8bg/s400/10.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Ustalamy, że check-in ma być odrzucony jeśli wybrane przez nas testy nie przejdą ("Fail Build On Test Failure" - True). </span><br />
<span style="font-family: Verdana,sans-serif;">Aby wybrać testy, które mają być wywoływane wpisujemy w opcję "Category Filter" jej nazwę np. "VIT" (Very Important Tests).</span><br />
<span style="font-family: Verdana,sans-serif;">Zapisujemy builda i "eto wsio".</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">3. Trochę przykładów</span></b></span><br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: Verdana,sans-serif;">Aby zaprezentować jak działa nasz build utwórzmy projekty o strukturze.</span><a href="http://2.bp.blogspot.com/-YlAOUIxxmbs/TtpdCrjJ65I/AAAAAAAAAPo/FE9n9pqAVPA/s1600/11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-YlAOUIxxmbs/TtpdCrjJ65I/AAAAAAAAAPo/FE9n9pqAVPA/s1600/11.png" /></a></div>
<br />
<span style="font-family: Verdana,sans-serif;">Projekt OneCardMaster jest to "Class Library", OneCardMasterTest - "Test Project".</span><br />
<span style="font-family: Verdana,sans-serif;">Dodajemy klasę ClassToTest wyglądającą:</span><span style="font-family: Verdana,sans-serif;">
</span></div>
</div>
<div dir="ltr" style="text-align: left;" trbidi="on">
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public static class ClassToTest
{
public static bool VeryImportantFunction()
{
return true;
}
public static bool Function1()
{
return true;
}
public static bool Function2()
{
return true;
}
public static bool Function3()
{
return true;
}
}</pre>
<div style="text-align: justify;">
<br />
<span style="font-family: Verdana,sans-serif;">Jak widać jest to prosta klasa, która jedynie symuluje działanie systemu. Mamy tutaj cztery funkcje w tym jedną bardzo ważną. Do projektu testowego dodajemy klasę sprawdzającą poprawność jej działania.</span></div>
</div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">[TestClass]
public class ClassToTestTest
{
private TestContext testContextInstance;
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
[TestMethod]
[TestCategory("VIT")]
public void VeryImportantFunction_ReturnsTrue()
{
Assert.IsTrue(ClassToTest.VeryImportantFunction());
}
[TestMethod]
public void Function1_ReturnsTrue()
{
Assert.IsTrue(ClassToTest.Function1());
}
[TestMethod]
public void Function2_ReturnsTrue()
{
Assert.IsTrue(ClassToTest.Function2());
}
[TestMethod]
public void Function3_ReturnsTrue()
{
Assert.IsTrue(ClassToTest.Function3());
}
}
</pre>
<div style="text-align: justify;">
<br />
<span style="font-family: Verdana,sans-serif;">Do każdej metody dodana została funkcja sprawdzająca jej poprawność. Jak łatwo zauważyć na ten moment wszystkie testy przechodzą.</span><br />
<span style="font-family: Verdana,sans-serif;">Przechodzimy do Team Explorera i naciskamy przycisk Check In. Po zaakceptowaniu pojawi nam się nowe okno (</span><span style="font-family: Verdana,sans-serif;">jest to zmiana w stosunku do tego co mieliśmy przed konfiguracją builda wejściowego)</span><span style="font-family: Verdana,sans-serif;">.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-P1xbIWLwDrI/TtplTS1Bv6I/AAAAAAAAAPw/XkpEWJqg7jo/s1600/12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="192" src="http://3.bp.blogspot.com/-P1xbIWLwDrI/TtplTS1Bv6I/AAAAAAAAAPw/XkpEWJqg7jo/s400/12.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Informuje nas ono o tym, że nasze pliki zostaną wrzucone "na półkę". TFS sprawdzi poprawność zmian i jeżeli weryfikacja przebiegnie poprawnie to doda je do repozytorium. Naciskamy przycisk Build Changes.</span><br />
<span style="font-family: Verdana,sans-serif;">W naszym systemie zostanie uruchomiony wątek sprawdzający czy build się nie zakończył.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-utAuAKLftW0/TtpnNApOIZI/AAAAAAAAAP4/GFa_-dDJkjk/s1600/13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="183" src="http://2.bp.blogspot.com/-utAuAKLftW0/TtpnNApOIZI/AAAAAAAAAP4/GFa_-dDJkjk/s400/13.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Gdy status builda się zmieni otrzymamy o tym informację w postaci wyskakującego okna. Jeżeli wszystko zrobiliśmy poprawnie powinno wyglądać następująco:</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-g_e9QbFeqPY/TtpoJTa0CkI/AAAAAAAAAQA/ciifuZGMzaY/s1600/14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-g_e9QbFeqPY/TtpoJTa0CkI/AAAAAAAAAQA/ciifuZGMzaY/s400/14.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Mamy dwie opcje do wyboru:</span><br />
<span style="font-family: Verdana,sans-serif;">- Reconcile - odświeża status naszej lokalnej kopii repozytorium, czyści zmiany z pending changes itd.</span><br />
<span style="font-family: Verdana,sans-serif;">- Ignore - nic nie robi - nie odświeża repozytorium. Dopiero gdy zrobimy update to uaktualni nam się wersja</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Spróbujmy teraz zmienić metodę VeryImportantFunction na:</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public static bool VeryImportantFunction()
{
return false;
}
</pre>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Po takiej zmianie nasz test z kategorii "VIT" nie będzie przechodził i build wejściowy nie powinien się udać.</span><br />
<span style="font-family: Verdana,sans-serif;">Przejdźmy do Team Explorer i zróbmy Check In. Po zakończeniu builda powinniśmy zobaczyć okno informujące nas o niepowodzeniu:</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-gvuWPoFlE7M/Ttpv3E2VaoI/AAAAAAAAAQQ/aZx03N8C82U/s1600/15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="162" src="http://3.bp.blogspot.com/-gvuWPoFlE7M/Ttpv3E2VaoI/AAAAAAAAAQQ/aZx03N8C82U/s320/15.png" width="320" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">Podsumowanie</span></b></span><br />
<br />
<span style="font-family: Verdana,sans-serif;">W powyższym artykule starałem się przedstawić zasady dobrego korzystania z repozytorium, podstawy Continuous Integration oraz przykład jak zastosować to w praktyce przy użyciu TFS. Oczywiście jest to tylko wstęp, bo temat jest długi jak rzeka. Raczej nie będziecie znać po jego lekturze wszystkich odpowiedzi, ale liczę, że będziecie </span><span style="font-family: Verdana,sans-serif;">chociaż </span><span style="font-family: Verdana,sans-serif;">wiedzieć o co pytać. </span></div>
</div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-11857231028557597282011-11-22T19:06:00.001+01:002011-11-22T23:39:30.662+01:00Scrum i Team Foundation Server cz.4 - Tworzymy projekt<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">W po</span><span style="font-family: Verdana,sans-serif;">przednich wpisach opisałem ogólne zasady metodyki Scrum, przedstawiłem sposób instalacji i konfiguracji - TFS. W tym wpisie pokażę podstawowe zasady jak połączyć teorię z praktyką. Podobnie jak w poprzednich wpisach bazował będę na Team Foundation Server 11 DP, konieczne również będzie Visual Studio 11 DP.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Załóżmy, że chcemy wytworzyć grę komputerową - One Card Master. Gra ta będzie niczym innym niż uproszczoną wersją gry w wojnę. Każdy z graczy otrzymuje po jednej karcie - wygrywa osoba, która ma największą kartę.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"> </span></div>
<div style="text-align: justify;">
<b><span style="font-family: Verdana,sans-serif; font-size: large;">1. Połączenie z TFS</span></b></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"> </span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Uruchommy Visual Studio.</span><span class="st" style="font-family: Verdana,sans-serif;"> Posiada ona specjalną sekcję odpowiedzialną za elementy zarządzania projektem. Jeżeli nie jesteśmy połączeni widzimy tylko jedną opcję - "Connect to Team Foundation Server", po połączeniu pojawi się ich więcej. Wybieramy opcję połączenia.</span><div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-olFXNWF6QRg/TsP7B1ZP1tI/AAAAAAAAAIY/I6SvEmJ_E2Y/s1600/connectToTFS01.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="103" src="http://2.bp.blogspot.com/-olFXNWF6QRg/TsP7B1ZP1tI/AAAAAAAAAIY/I6SvEmJ_E2Y/s400/connectToTFS01.png" width="400" /></a></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">Ukaże nam się okno wyboru serwera, z którym chcemy się połączyć. Ponieważ jest to nasze pierwsze połączenie lista wyboru jest pusta.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-9ifM55RCGRs/Tsvu3WZmF4I/AAAAAAAAAI8/rWOV3iVoEco/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="285" src="http://4.bp.blogspot.com/-9ifM55RCGRs/Tsvu3WZmF4I/AAAAAAAAAI8/rWOV3iVoEco/s400/01.png" width="400" /></a></div>
<br />
<span style="font-family: Verdana,sans-serif;">Naciskamy przycisk "Servers" by zdefiniować połączenie. </span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-s6T3yK6nEwI/TsvwL4FYT-I/AAAAAAAAAJE/_wOsvkUro4k/s1600/02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="252" src="http://1.bp.blogspot.com/-s6T3yK6nEwI/TsvwL4FYT-I/AAAAAAAAAJE/_wOsvkUro4k/s400/02.png" width="400" /></a></div>
<br />
<span style="font-family: Verdana,sans-serif;">Ponieważ chcemy dodać nowe połączenie naciskamy przycisk "Add"</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-wZxpbx8dO1Q/TsvxJF0sdWI/AAAAAAAAAJM/7n17Sh0RzKE/s1600/03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="263" src="http://3.bp.blogspot.com/-wZxpbx8dO1Q/TsvxJF0sdWI/AAAAAAAAAJM/7n17Sh0RzKE/s400/03.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">W pole na górze wpisujemy nazwę (lub adres) naszego serwera - w moim przypadku jest to "win-mpmq6e2dm0c". Naciskamy "OK" i w oknie wyboru serwera "Close".</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-lriQYDpFccU/TsvyMKAKLeI/AAAAAAAAAJU/RxL4pmYtTlE/s1600/04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="229" src="http://3.bp.blogspot.com/-lriQYDpFccU/TsvyMKAKLeI/AAAAAAAAAJU/RxL4pmYtTlE/s320/04.png" width="320" /></a></div>
<span style="font-family: Verdana,sans-serif;"></span><br />
<span style="font-family: Verdana,sans-serif;"><br />Teraz w oknie wyboru serwera w liście rozwijalnej powinniśmy zobaczyć nasz serwer. Wybieramy go i naciskamy przycisk "Connect". Zostaniemy poproszeni o dane autoryzacyjne - podajmy dane administratora serwera.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">2. Utworzenie projektu</span></b></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Jesteśmy już połączeni z serwerem, możemy przejść zatem do utworzenia naszego projektu.</span><br />
<span style="font-family: Verdana,sans-serif;">Do zarządzania projektem służy "Team Explorer". Można go włączyć poprzez Menu=>View=>Team Explorer.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-MDWphJRRQYc/Tsvz-rK9zMI/AAAAAAAAAJc/6dxI4Zv7IiQ/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="296" src="http://2.bp.blogspot.com/-MDWphJRRQYc/Tsvz-rK9zMI/AAAAAAAAAJc/6dxI4Zv7IiQ/s320/05.png" width="320" /></a></div>
<br />
<span style="font-family: Verdana,sans-serif;">Aby utworzyć nowy projekt naciskamy "Create New Team Project".</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-z1-JfZG3YjU/Tsv01EtUYVI/AAAAAAAAAJk/UkjPIxbKYIg/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="351" src="http://3.bp.blogspot.com/-z1-JfZG3YjU/Tsv01EtUYVI/AAAAAAAAAJk/UkjPIxbKYIg/s400/06.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br />Wpisujemy nazwę naszego projektu i ewentualnie opis i kilkamy "Next".</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-prv6CuiPfPk/Tsv19NsgltI/AAAAAAAAAJs/vP8Cgnl25xI/s1600/07.png" imageanchor="1"><img border="0" height="350" src="http://1.bp.blogspot.com/-prv6CuiPfPk/Tsv19NsgltI/AAAAAAAAAJs/vP8Cgnl25xI/s400/07.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"> </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Team Foundation Server pozwala na definiowanie i używanie szablonów projektów. W ich obrębie można m.in. definiować typy zadań, przepływy między nimi. TFS dostarcza od razu kilka z nich oraz pozwala na pobranie innych z MSDN. Ponieważ chcemy prowadzić nasz projekt przy pomocy metodyki Scrum, wybieramy szablon "Microsoft Visual Studio Scrum 2.0 - Preview 1" i naciskamy przycisk "Finish". Nastąpi teraz proces konfiguracji nowego projektu, po jego pomyślnym zakończeniu naciskamy przycisk "Close".</span><br />
<span style="font-family: Verdana,sans-serif;">Po dodaniu projektu Visual Studio automatycznie połączy nas z nim - widoczne to będzie od razu po wyglądzie menu Team Explorera.</span><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-57JLYxdOBHM/Tsv5shMOdJI/AAAAAAAAAJ0/_8bLAvJv2YA/s1600/08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="290" src="http://4.bp.blogspot.com/-57JLYxdOBHM/Tsv5shMOdJI/AAAAAAAAAJ0/_8bLAvJv2YA/s320/08.png" width="320" /></a></div>
<br />
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">3. Utworzenie zespołu</span></b></span><br />
<span style="font-family: Verdana,sans-serif;"> </span><br />
<span style="font-family: Verdana,sans-serif;"> Podobnie jak w filmach typu "Parszywa dwunastka", czy "7 wspaniałych" pierwszym krokiem w konfiguracji naszego projektu jest utworzenie zespołu. </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Konta w TFS powiązane są z kontami systemowymi. Możemy tego dokonać poprzez systemowe okno zarządzania komputerem (dostępne przez Start => All Programs => Administrative Tools=> Computer Management).</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-ldGg8eYZwEw/Tsv7-uQm-_I/AAAAAAAAAJ8/3s58f7_CRfg/s1600/09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="247" src="http://1.bp.blogspot.com/-ldGg8eYZwEw/Tsv7-uQm-_I/AAAAAAAAAJ8/3s58f7_CRfg/s400/09.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Dodajemy kilku "Janów Kowalskich" w celach testowych i zamykamy okno.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">TFS przy konfiguracji serwera tworzy bardzo przydatną rzecz jaką jest strona pozwalająca na zdalny do niego dostęp. Pozwala ona w wygodny sposób zarządzać zadaniami, użytkownikami i procesami projektu. Dalszej konfiguracji będziemy dokonywać przy jego pomocy. Aby się do niej dostać naciskamy "Web Access" w Team Explorerze.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-JBbLFu5K7yg/Tsv-FxMUV-I/AAAAAAAAAKE/Bb6fjOVq8_Y/s1600/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="http://1.bp.blogspot.com/-JBbLFu5K7yg/Tsv-FxMUV-I/AAAAAAAAAKE/Bb6fjOVq8_Y/s400/10.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Domyślnie została utworzona grupa projektowa dla naszego projektu. Aby dodać do niej inne osoby klikamy na </span><span style="font-family: Verdana,sans-serif;">"My Team" oraz w kolejnym ekranie przycisk "Administration" (znajdujący się w prawym </span><span style="font-family: Verdana,sans-serif;">górnym </span><span style="font-family: Verdana,sans-serif;">rogu).</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-7ImAM8ApDXE/TswBMNGNbeI/AAAAAAAAAKU/TMZDfwAsQEU/s1600/11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-7ImAM8ApDXE/TswBMNGNbeI/AAAAAAAAAKU/TMZDfwAsQEU/s400/11.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Wchodzimy do sekcji "members", w liście rozwijalnej "Actions" wybieramy "Manage Team Membership".</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-FydjZRtgrgg/TswCehz4O9I/AAAAAAAAAKc/IFvmXiStDqs/s1600/12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="http://2.bp.blogspot.com/-FydjZRtgrgg/TswCehz4O9I/AAAAAAAAAKc/IFvmXiStDqs/s400/12.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Aby dodać użytkownika naciskamy przycisk "add members". </span><br />
<span style="font-family: Verdana,sans-serif;"> </span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-PqzlYx76Xs4/TswEUy966yI/AAAAAAAAAKk/LZOH29B49w4/s1600/13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="170" src="http://1.bp.blogspot.com/-PqzlYx76Xs4/TswEUy966yI/AAAAAAAAAKk/LZOH29B49w4/s400/13.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"> </span><br />
<span style="font-family: Verdana,sans-serif;"> </span><br />
<span style="font-family: Verdana,sans-serif;">W pole wpisujemy użytkownika, którego chcemy dodać, naciskamy "check name", a następnie "Save Changes".</span><br />
<span style="font-family: Verdana,sans-serif;"></span><br />
<span style="font-family: Verdana,sans-serif;"><br />Należy dodać jeszcze naszą grupę projektową do grupy uprawnień pozwalającej na dostęp do projektu i działanie na nim. Dokonujemy tego naciskając link z nazwą naszego projektu znajdujący się w górnym menu strony.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-yQ8ngDHUQxc/TswGKOrMhkI/AAAAAAAAAKs/0imdj-w_qTo/s1600/14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="208" src="http://2.bp.blogspot.com/-yQ8ngDHUQxc/TswGKOrMhkI/AAAAAAAAAKs/0imdj-w_qTo/s400/14.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Przechodzimy do zakładki "project groups" i wybieramy grupę uczestników projektu - "contributors".</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-jkAqVAAn9S0/TswHMGLXLBI/AAAAAAAAAK0/3qpBw2o54xg/s1600/15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="http://2.bp.blogspot.com/-jkAqVAAn9S0/TswHMGLXLBI/AAAAAAAAAK0/3qpBw2o54xg/s400/15.png" width="400" /></a></div>
<br />
<span style="font-family: Verdana,sans-serif;">W sekcji "Group membership" naciskamy przycisk "manage membership". W znanym nam już oknie wybieramy "add tfs group" i z listy wybieralnej bierzemy grupę [One Card Master]\My Team. Dzięki temu, każdy nowy użytkownik, którego dołączymy do zespołu projektowego automatycznie nabędzie stosowne uprawnienia.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;"><b>4. Przygotowania do pierwszego sprintu</b></span></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Mając wybrany i utworzony zespół możemy przystąpić do planowania projektu. Zgodnie z metodyką Scrum będziemy go dzielić na Sprinty oraz pomocniczo grupować je w Release'y. Grupowanie takie jest przydatne z tego względu, że pozwala na lepszą motywację, grupowanie faz oddawania projektu klientowi (np. jeden release to utworzenie konkretnego modułu). Tak jak wspomniałem we wcześniejszym artykule długość Sprintu być w przedziale 2-4 tygodnie (z tym, że każdy Sprint powinien trwać tyle samo). Liczba sprintów w Releasie też jest kwestią ustaleń.</span><br />
<span style="font-family: Verdana,sans-serif;">Dostęp do Sprintów oraz Release'ów znajduje się w sekcji Iterations.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-AaZeTmGxXMw/TswKckOz_fI/AAAAAAAAAK8/0lEJz3uxz6E/s1600/16.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="305" src="http://4.bp.blogspot.com/-AaZeTmGxXMw/TswKckOz_fI/AAAAAAAAAK8/0lEJz3uxz6E/s400/16.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Jak widać zostały utworzone 4 releasy, każdy po 6 sprintów. Do celów testowych tak dużo nie jest nam potrzebne. Usuńmy tak elementy by został nam jeden Release składający się z 4 Sprintów.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-XKwp4p8ncz0/TswLNu07OjI/AAAAAAAAALE/rmQKkYlENBY/s1600/17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-XKwp4p8ncz0/TswLNu07OjI/AAAAAAAAALE/rmQKkYlENBY/s1600/17.png" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Każdy ze sprintów będzie trwał 2 tygodnie. Dobrą zasadą jest od razu zaplanowanie dat startu i końca kolejnych sprintów. Efekt powinie wyglądać podobnie jak na poniższym screenie:</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-QZi9iPLyokw/TswMWWXb7VI/AAAAAAAAALM/DLm0GE08pTM/s1600/18.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="159" src="http://1.bp.blogspot.com/-QZi9iPLyokw/TswMWWXb7VI/AAAAAAAAALM/DLm0GE08pTM/s320/18.png" width="320" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Zwykle planując projekt dzielimy zadania na grupy np. wg biznesowych zasad (np. modułami) lub programistycznych kategorii (np. baza danych, serwer aplikacji, klient). Takie grupowanie można też dokonać w TFS poprzez zakładkę "areas".</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-ArnLmR92LMk/TswOwbA1F5I/AAAAAAAAALU/jDZMRlBXfec/s1600/19.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="172" src="http://1.bp.blogspot.com/-ArnLmR92LMk/TswOwbA1F5I/AAAAAAAAALU/jDZMRlBXfec/s400/19.png" width="400" /></a></div>
<br />
<br />
<span style="font-family: Verdana,sans-serif;">Ja utworzyłem 3 zgodnie z planowanymi modułami:</span><br />
<span style="font-family: Verdana,sans-serif;">- Administracja</span><br />
<span style="font-family: Verdana,sans-serif;">- Ekran Gry</span><br />
<span style="font-family: Verdana,sans-serif;">- Panel użytkownika</span><br />
<span style="font-family: Verdana,sans-serif;">Oczywiście grupy można zagnieżdżać jeszcze głębiej, nie musi to być płaska struktura jak w tym przykładzie.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;"><b>5. Planowanie zadań</b></span></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Zadania planujemy poprzez zakładkę "backlog" projektu. Wychodzimy z administracji (przez link "Exit administration) i przechodzimy do niej.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-CxG5thHXzBg/TswQqWO6H_I/AAAAAAAAALc/1s-hnh-1Uwo/s1600/20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="145" src="http://4.bp.blogspot.com/-CxG5thHXzBg/TswQqWO6H_I/AAAAAAAAALc/1s-hnh-1Uwo/s400/20.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><span id="goog_1386060738"></span><span id="goog_1386060739"></span></span><br />
<span style="font-family: Verdana,sans-serif;">W TFS przyjęto, że zadania grupowane są w historie użytkownika (Product Backlog Item, Bug) opisujące konkretny przypadek do zrealizowania. Gdy uznamy, że chcemy, żeby była realizowana powinniśmy przypisać do niej co najmniej jedno zadanie. Jest to odzwierciedlenie standardowego procesu tworzenia systemów informatycznych. Jako programiści zwykle dostajemy opis zadania w postaci przepływu biznesowego. Musimy wtedy zwykle dokonać zmian na bazie, dodać metody na serwisie i oprogramować klienta. </span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Historię użytkownika (PBI) dodajemy poprzez przycisk "Add".</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-pxwLFDQHlsA/TswVl4TNNJI/AAAAAAAAALs/l-MOsaZSBDI/s1600/21.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="170" src="http://2.bp.blogspot.com/-pxwLFDQHlsA/TswVl4TNNJI/AAAAAAAAALs/l-MOsaZSBDI/s400/21.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Posiada ono następujące główne elementy:</span><br />
<span style="font-family: Verdana,sans-serif;">- Assigned To - osoba odpowiedzialna za realizację historii użytkownika</span><br />
<span style="font-family: Verdana,sans-serif;">- Status - aktualny status zadania</span><br />
<span style="font-family: Verdana,sans-serif;">- Reason - powód dokonania akcji</span><br />
<span style="font-family: Verdana,sans-serif;">- Effort - wysiłek, który należy wykonać aby skończyć to PBI. Wyrażone to jest w story pointach (jaki czas ma jeden story point jest kwestią ustalenia w projekcie)</span><br />
<span style="font-family: Verdana,sans-serif;">- Business Value - jest to wartość, jaką wniesie ta historia użytkownika do projektu</span><br />
<span style="font-family: Verdana,sans-serif;">- Area - grupa zadań, do którego zalicza się PBI</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Od razu przy dodawaniu historii użytkownika można zdefiniować zadania do niego. Można tego dokonać przechodząc do zakładki "Tasks" i naciśnięcie przycisku "New".</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-L15i0eyaPVg/TswWSE-uOdI/AAAAAAAAAL0/mBIW5bH8zm0/s1600/22.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://3.bp.blogspot.com/-L15i0eyaPVg/TswWSE-uOdI/AAAAAAAAAL0/mBIW5bH8zm0/s400/22.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Zadanie posiada m.in. pola:</span><br />
<span style="font-family: Verdana,sans-serif;">- Assigned To - użytkownik, do którego zostało przypisane zadanie</span><br />
<span style="font-family: Verdana,sans-serif;">- State - aktualny status zadania</span><br />
<span style="font-family: Verdana,sans-serif;">- Reason - powód dokonywanej akcji</span><br />
<span style="font-family: Verdana,sans-serif;">- Blocked - czy zadanie jest zablokowane (nie powinno być aktualnie robione)</span><br />
<span style="font-family: Verdana,sans-serif;">- Description - opis</span><br />
<span style="font-family: Verdana,sans-serif;">- Remaining Work - effor pozostały do zakończenia zadania</span><br />
<span style="font-family: Verdana,sans-serif;">- Backlog Priority - priorytet zadania</span><br />
<span style="font-family: Verdana,sans-serif;">- Activity - rodzaj czynności wykonywanej w zadaniu (np. Development, Documentation)</span><br />
<span style="font-family: Verdana,sans-serif;">- Area - grupa zadań, do których zalicza się ten task</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Po dodaniu PBI i zadań w widoku rejestru produktu (backlog) pojawi się nowy wpis.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;"><b>6. Realizacja sprintu</b></span></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Zarządzanie realizacją sprintu można zobaczyć w zakładce "board".</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-wEttiOO-ulU/TswZkWFvbeI/AAAAAAAAAL8/u-4SURvVIbI/s1600/23.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="170" src="http://1.bp.blogspot.com/-wEttiOO-ulU/TswZkWFvbeI/AAAAAAAAAL8/u-4SURvVIbI/s400/23.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Na tym ekranie widać wszystkie historie użytkownika oraz ich zadania w obrębie aktualnego sprintu. </span><br />
<span style="font-family: Verdana,sans-serif;">Tablica (dashboard) jest klasycznym Scrumowym widokiem. Zadania podzielone są na trzy grupy:</span><br />
<span style="font-family: Verdana,sans-serif;">- To Do - nie rozpoczęte,</span><br />
<span style="font-family: Verdana,sans-serif;">- In Progress - w trakcie robienia,</span><br />
<span style="font-family: Verdana,sans-serif;">- Done - skończone.</span><br />
<span style="font-family: Verdana,sans-serif;">W prostocie tego widoku tkwi jego siła. Widać na nim dokładnie, które zadania zostały już rozpoczęte, kto się czym zajmuje aktualnie oraz co zostało skończone. </span><br />
<span style="font-family: Verdana,sans-serif;">Zadania można w prosty sposób poprzez przeciągnięcie przenosić pomiędzy jednym statusem a drugim. Poprzez podwójne kliknięcie wchodzić do ich edycji. W prawym górnym rogu widoczny jest również Burndown Chart - czyli wykres postępu prac (o nim postaram się napisać w osobnym wpisie).</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">7. Dodanie projektu do kontroli wersji</span></b></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Jedyną rzeczą, która pozostała nam do zrobienia by można było zacząć realizować projekt jest dodanie plików do kontroli wersji.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Wracamy do Visual Studio i Team Explorera. Naciskamy przycisk Source Control Explorer.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-_jHRBZmBGVc/TswciZb-vpI/AAAAAAAAAME/pMx5BtfTRn8/s1600/24.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="308" src="http://1.bp.blogspot.com/-_jHRBZmBGVc/TswciZb-vpI/AAAAAAAAAME/pMx5BtfTRn8/s400/24.png" width="400" /></a></div>
<br />
<span style="font-family: Verdana,sans-serif;">Wybieramy nasz projekt i naciskamy "Map to Local Folder". Wybierzemy to aby określić, w którym miejscu na naszym lokalnym komputerze będą przechowywane pliki projektu. Po dokonaniu mapowania, naciskamy przycisk "New Folder" aby dodać folder o nazwie "src" (z kodami źródłowymi).</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-KY_02bjY-o4/Tswfuq6zgSI/AAAAAAAAAMM/lOANxjRUmns/s1600/25.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="http://4.bp.blogspot.com/-KY_02bjY-o4/Tswfuq6zgSI/AAAAAAAAAMM/lOANxjRUmns/s200/25.png" width="200" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Poprzez przycisk "New Project" w oknie "Start Page" dodajemy nowy projekt z lokacją w zmapowanym folderze. Zaznaczamy dodatkowo "Add to source control".</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-ARVH-Amtkck/TswgZSvXQQI/AAAAAAAAAMU/3lxyw5KhTfM/s1600/26.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="http://2.bp.blogspot.com/-ARVH-Amtkck/TswgZSvXQQI/AAAAAAAAAMU/3lxyw5KhTfM/s400/26.png" width="400" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Wszystkie foldery i pliki, które utworzyliśmy do tego momentu znajdują się tylko lokalnie na naszym dysku. Aby zmiany zostały wrzucone na serwer należy przejść do Team Explorera, nacisnąć "My Work", a następnie "Check In".</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-ZtnnnA4V_zA/TswimA-StPI/AAAAAAAAAMc/UvlffXTGeR4/s1600/27.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://1.bp.blogspot.com/-ZtnnnA4V_zA/TswimA-StPI/AAAAAAAAAMc/UvlffXTGeR4/s400/27.png" width="255" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Zobaczymy listę wszystkich naszych zmian. Dobrym zwyczajem jest podanie komentarza przy check inie. Po naciśnięciu przycisku Check In zmiany zostaną wrzucone na serwer.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Podstawowa konfiguracja TFS do pracy z projektem została dokonana. W kolejnych wpisach postaram się przybliżyć każdy z tych kroków dokładniej. </span><br />
<span style="font-family: Verdana,sans-serif;"> </span></div>
</div>
</div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-48674050372585730812011-11-16T12:11:00.001+01:002011-11-17T09:49:15.712+01:00Scrum i Team Foundation Server cz.3 - Wystawiamy się na zewnątrz<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Tym razem wpis będzie poświęcony dodatkowej czynności, nie związanej bezpośrednio ze Scrum albo TFS. Pokażę prosty sposób w jaki można udostępnić swój serwer nie posiadając stałego łącza IP, łącząc się przez router. Nie uważam, że jest to opcja najlepsza, ani najbezpieczniejsza, ale jest prosta i może być punktem wyjściowym do lepszej konfiguracji.</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Jak zrobić, żeby można było się połączyć z serwerem gdy nie posiada on stałego numer IP? Można to zrobić przy pommechanizmu DynDNS. Jeżeli chcemy uruchomić serwer np. ze stroną www lub podglądem kamer monitoringu dostępny z każdego miejsca w Internecie, a nie posiadamy stałego adresu IP, tylko otrzymujemy go dynamicznie z serwera DHCP (jak np. w przypadku Neostrady) musimy skorzystać z usługi DDNS (Dynamic Domain Name System) czyli usługi dynamicznego serwera nazw. </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Jak działa DDNS? Opis tego mechanizmu można znaleźć np. na stronie <a href="http://www.dipol.com.pl/do_czego_sluzy_ddns_dynamic_domain_name_system_i_jak_go_uzywac__bib93.htm">dipol.com.pl</a>. Oto wycinek z niego:</span></div>
<div style="text-align: justify;">
<i><span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><span style="font-family: Arial,Helvetica,sans-serif;">"</span><span style="font-family: Verdana,sans-serif;">Z pomocą idzie usługa DDNS, która tak jak DNS posiada bazę danych z
wpisami zależności adresu domenowego z numerycznym, ale może być
aktualizowana w dowolnej chwili czasu przez posiadacza domeny. Dzięki
temu serwer może być osiągalny pod jedną, ustaloną nazwą niezależnie od
tego, jaki adres IP w danej chwili posiada. Z tego powodu z serwerem
można komunikować się tylko za pomocą adresu domenowego przetłumaczonego
przez serwer DDNS (chyba, że znamy aktualny adres numeryczny serwera,
ale nigdy nie wiemy jak długo będzie on obowiązywał).</span><span style="font-family: Arial,Helvetica,sans-serif;">"</span></i></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br />UsuW tym tutorialu przedstawię jak skonfigurować DynDNS przy pomocy serwisu <a href="http://www.no-ip.com/">www.no-ip.com</a>.</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><b><span style="font-family: Arial,Helvetica,sans-serif;">Utworzenie konta i konfiguracja na Dyn.com</span></b></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Tak jak zostało wspomniane wcześniej, aby móc korzystać z DynDNS konieczne jest utworzenie konta na stronie dostarczającej tą usługę. Proces ten najlepiej przeprowadzić na komputerze, który chcemy wystawić jako serwer na zewnątrz.</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">1. Wchodzimy na stronę <a href="http://www.no-ip.com/services/managed_dns/free_dynamic_dns.html" target="_blank">www.no-ip.com/services/managed_dns/free_dynamic_dns.html</a>. Powinna ona wyglądać następująco:</span></div>
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-TbmwOI3HyBs/TsPe_kAvvkI/AAAAAAAAAF4/UlksgYvNoLQ/s1600/dyndns01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="172" src="http://2.bp.blogspot.com/-TbmwOI3HyBs/TsPe_kAvvkI/AAAAAAAAAF4/UlksgYvNoLQ/s400/dyndns01.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-d1o3I8o4dzs/TsOhb9-y6OI/AAAAAAAAAFw/TsuUpvhqjoE/s1600/dyndns01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Wpisujemy nasz adres e-mail i naciskamy przycisk "Sign Up Now!".</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">2. W kolejnej stronie wypełniamy</span><span style="font-family: Arial,Helvetica,sans-serif;"> naszymi danymi</span><span style="font-family: Arial,Helvetica,sans-serif;"> formularz rejestracji. Akceptujemy warunki licencyjne i naciskamy przycisk "I Accept, Create my Account".</span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-5fdn6M1TvZw/TsPfzMPNikI/AAAAAAAAAGA/nX9yRUjmTEs/s1600/dyndns02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="172" src="http://3.bp.blogspot.com/-5fdn6M1TvZw/TsPfzMPNikI/AAAAAAAAAGA/nX9yRUjmTEs/s400/dyndns02.png" width="400" /></a></div>
<br />
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">3. Jeżeli wszystko wprowadziliśmy poprawnie pojawi nam się ekran informujący o konieczności potwierdzenia podanego przez nas adresu e-mail.</span></div>
<span style="font-family: Arial,Helvetica,sans-serif;"> </span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-rlK-Rags2og/TsPg5ffaeUI/AAAAAAAAAGI/8gRDhYn2DuU/s1600/dyndns03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="172" src="http://3.bp.blogspot.com/-rlK-Rags2og/TsPg5ffaeUI/AAAAAAAAAGI/8gRDhYn2DuU/s400/dyndns03.png" width="400" /></a></div>
<span style="font-family: Arial,Helvetica,sans-serif;"> </span><br />
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">4. Wchodzimy na swoją skrzynkę pocztową i naciskamy link aktywacyjny w mailu, który otrzymaliśmy od portalu NO-IP. Po kliknięciu powinna pojawić się strona:</span></div>
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-5pZPHO6ei0Q/TsPhq0QUzUI/AAAAAAAAAGQ/wFSXaomK-SQ/s1600/dyndns05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="172" src="http://3.bp.blogspot.com/-5pZPHO6ei0Q/TsPhq0QUzUI/AAAAAAAAAGQ/wFSXaomK-SQ/s400/dyndns05.png" width="400" /></a></div>
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">Naciskamy link "login".</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">5. W kolejnym ekranie wpisujemy swoje dane autoryzacyjne i naciskamy przycisk "Login".</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-h5Jvqogb5Bo/TsPh9b7rBCI/AAAAAAAAAGY/YQBg2AMiTgQ/s1600/dyndns06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="172" src="http://4.bp.blogspot.com/-h5Jvqogb5Bo/TsPh9b7rBCI/AAAAAAAAAGY/YQBg2AMiTgQ/s400/dyndns06.png" width="400" /></a></div>
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">6. W kolejnym widoku naciskamy przycisk "Add a Host".</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-1mPNEOTExwI/TsPipsVGdyI/AAAAAAAAAGg/xos_VTtL9qk/s1600/dyndns07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="http://3.bp.blogspot.com/-1mPNEOTExwI/TsPipsVGdyI/AAAAAAAAAGg/xos_VTtL9qk/s400/dyndns07.png" width="400" /></a></div>
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span><br />
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">7. Ukaże nam się ekran konfiguracji naszego adresu. Do celów naszej konfiguracji wystarczą nam domyślne wartości. Jedyne co musimy zrobić do wpisać unikatowy identyfikator np. "testtutorialscrumitfs" i nacisnąć przycisk "Create Host".</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-hsDf8CaHVfs/TsPkCl3WbdI/AAAAAAAAAGo/-T4JcUFgcZU/s1600/dyndns08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="http://1.bp.blogspot.com/-hsDf8CaHVfs/TsPkCl3WbdI/AAAAAAAAAGo/-T4JcUFgcZU/s400/dyndns08.png" width="400" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Udało nam się zarejestrować nasz serwer w serwisie DynDNS. Kolejnym krokiem jest:</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: large;"><b>Skonfigurowanie routera do obsługi DynDNS</b></span></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Nowe routery zwykle dają możliwość konfiguracji DynDNS. Dzięki niej po zmianie adresu IP routera powiadomi on o tym automatycznie serwis DynDNS. </span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Przykładowa konfiguracja zostanie pokazana na przykładzie modelu DI-524 firmy D-Link.</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">1. Otwieramy stronę konfiguracyjną routera pod adresem <a href="http://192.168.0.1/" target="_blank">http://192.168.0.1/</a> . Standardowo dane autoryzacyjne to dla niego:</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">- login - admin</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">- hasło - admin</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Otworzy nam się strona:</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-lIT5Yy8SVfU/TsPnKza4EdI/AAAAAAAAAGw/lLwpyunGoTA/s1600/dyndns09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="http://2.bp.blogspot.com/-lIT5Yy8SVfU/TsPnKza4EdI/AAAAAAAAAGw/lLwpyunGoTA/s400/dyndns09.png" width="400" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Wchodzimy do zakładki "Advanced".</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">2. Na następnym ekranie naciskamy przycisk "DDNS"</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-_Xq93IHDRO8/TsPnpfwkPZI/AAAAAAAAAG4/zs9QeTEwRHQ/s1600/dyndns10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="http://1.bp.blogspot.com/-_Xq93IHDRO8/TsPnpfwkPZI/AAAAAAAAAG4/zs9QeTEwRHQ/s400/dyndns10.png" width="400" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">3. Pojawi nam się ekran do konfiguracji DynDNS. Wybieramy w nim serwis No-IP.com. Wpisujemy nasz hostname (</span><span style="font-family: Arial,Helvetica,sans-serif;">np. "testtutorialscrumitfs") oraz swój login i hasło. Zatwierdzamy przyciskiem "Apply".</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-68EVz-og6sE/TsPvWqZS-yI/AAAAAAAAAHA/XQ8moI9CbuM/s1600/dyndns11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="http://3.bp.blogspot.com/-68EVz-og6sE/TsPvWqZS-yI/AAAAAAAAAHA/XQ8moI9CbuM/s400/dyndns11.png" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Po tych krokach skonfigurowaliśmy nasz router do współpracy z serwisem DynDNS. Pozostało, jednak, jeszcze kilka rzeczy do zrobienia.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">Konfiguracja przekierowania portów</span></b></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Team Foundation Server nasłuchuje pod portem 8080</span><span style="font-family: Verdana,sans-serif;"> na naszym serwerze</span><span style="font-family: Verdana,sans-serif;">. Gdy użytkownik będzie chciał połączyć się z Team Foundation serwer pod adresem DynDNS łączyć się będzie z routerem. Musimy skonfigurować go tak, żeby wiedział, o konieczności przekierowania połączenia z portem 8080 na nasz serwer (tzw. <a href="http://pl.wikipedia.org/wiki/Przekierowanie_port%C3%B3w" target="_blank">port forwarding</a>) . Oto jak można to skonfigurować na routerze</span> <span style="font-family: Arial,Helvetica,sans-serif;">DI-524 firmy D-Link.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Wchodzimy na stronę konfiguracji routera (</span><span style="font-family: Arial,Helvetica,sans-serif;"><a href="http://192.168.0.1/" target="_blank">http://192.168.0.1/</a></span><span style="font-family: Arial,Helvetica,sans-serif;">) i przechodzimy do ustawień zaawansowanych (zakładka "Advanced")</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-XxcmBF6ANPQ/TsPxz_yhtYI/AAAAAAAAAHI/BGiAvWHw5PY/s1600/dyndns12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="http://3.bp.blogspot.com/-XxcmBF6ANPQ/TsPxz_yhtYI/AAAAAAAAAHI/BGiAvWHw5PY/s400/dyndns12.png" width="400" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Wpisujemy w kolejne pola:</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">- Name - nazwę przekierowania (np. TFS)</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">- Private IP - wpisujemy IP naszego serwera</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">- Protocol Type - TCP</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">- Private Port - 8080</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">- Public Port - 8080</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">- Schedule - Always</span></div>
<div style="text-align: justify;">
<span style="font-family: Arial,Helvetica,sans-serif;">Naciskamy przycisk "Apply". </span><span class="st" style="font-family: Verdana,sans-serif;">Voilà!</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><span style="font-size: large;"><b>Konfiguracja Firewalla na serwerze</b></span></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">Pozostała nam jeszcze ostatnia rzecz. Skonfigurowanie naszego serwera tak by przyjmował połączenia z zewnątrz na porcie 8080.</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">Konfiguracja zostanie pokazana na przykładzie Windows Server 2008.</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"> </span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">1. Wchodzimy do ustawień Firewalla (Start=>Administrative Tools =>Windows Firewall wih Advanced Security)</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-LK0dhTJgIqE/TsP0bUC6BDI/AAAAAAAAAHQ/oa-Ut60z9xQ/s1600/dyndns13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="http://4.bp.blogspot.com/-LK0dhTJgIqE/TsP0bUC6BDI/AAAAAAAAAHQ/oa-Ut60z9xQ/s400/dyndns13.png" width="400" /></a></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">2. Zobaczymy okno konfiguracji zasad Firewalla. Będziemy ustalać zarówno regułę połączeń przychodzących (Inbound Rules) jak i wychodzących (Outbound Rules).</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-9OFFgQEooPw/TsP0w4RdL7I/AAAAAAAAAHY/kXnsCKIs6AM/s1600/dyndns14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="http://3.bp.blogspot.com/-9OFFgQEooPw/TsP0w4RdL7I/AAAAAAAAAHY/kXnsCKIs6AM/s400/dyndns14.png" width="400" /></a></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">Naciskamy przycisk "New Rule" znajdujący się w prawym górnym rogu.</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">3. Otworzy nam się wizard konfiguracji reguły Firewalla.</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-6syIp4oh9CE/TsP1VM82CII/AAAAAAAAAHg/nXsy2BvyEog/s1600/dyndns15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="http://1.bp.blogspot.com/-6syIp4oh9CE/TsP1VM82CII/AAAAAAAAAHg/nXsy2BvyEog/s400/dyndns15.png" width="400" /></a></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">Wybieramy opcję "Port" i naciskamy przycisk "Next"</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">4. W kolejnym oknie zaznaczamy opcję "TCP" i wpisujemy konkretny port - 8080 ("Specific local ports"). Klikamy "Next".</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-YGNtatfMUhE/TsP1u7hHMJI/AAAAAAAAAHo/4TTo7bxVHGE/s1600/dyndns16.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="http://3.bp.blogspot.com/-YGNtatfMUhE/TsP1u7hHMJI/AAAAAAAAAHo/4TTo7bxVHGE/s400/dyndns16.png" width="400" /></a></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">5. Pozwalamy na połączenie z tym portem ("Allow the connection") i przechodzimy dalej.</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-w6C24Bqyt9c/TsP2MeCpzAI/AAAAAAAAAHw/3_SFbPNg9ME/s1600/dyndns17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="http://3.bp.blogspot.com/-w6C24Bqyt9c/TsP2MeCpzAI/AAAAAAAAAHw/3_SFbPNg9ME/s400/dyndns17.png" width="400" /></a></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">6. Zostawiamy domyślne ustawienia dostępu (Domain, Private, Public) i przechodzimy do kolejnego ekranu.</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-qbwrZKC2ZdE/TsP2ci9B0CI/AAAAAAAAAH4/HQQWl8QctcM/s1600/dyndns18.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="http://3.bp.blogspot.com/-qbwrZKC2ZdE/TsP2ci9B0CI/AAAAAAAAAH4/HQQWl8QctcM/s400/dyndns18.png" width="400" /></a></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">7. W ostatnim ekranie wizarda wpisujemy nazwę (np. TFS) i pełni samozadowolenia naciskamy przycisk "Finish".</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-aVekJ-VzyvI/TsP2wStUY0I/AAAAAAAAAIA/YsTUh9cdMIw/s1600/dyndns19.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="http://4.bp.blogspot.com/-aVekJ-VzyvI/TsP2wStUY0I/AAAAAAAAAIA/YsTUh9cdMIw/s400/dyndns19.png" width="400" /></a></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">8. Pozostało nam przeprowadzić analogiczny proces dla reguły połączeń wychodzących. W głównym ekranie przechodzimy do "Outbound rules" i wciskamy przycisk "New Rule". Wizard jest taki sam jak w przypadku reguły przychodzącej, więc oszczędzę Wam i sobie mojej pisaniny wierząc, że sobie poradzicie.</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><span style="font-size: large;"><b>Test poprawności działania konfiguracji</b></span></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">Najprościej przetestować konfigurację próbując się z TFS przez Visual Studio.</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"> </span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">1. Otwieramy Visual Studio (np. wersję 11). Menu => Team => Connect To Team Foundation Server</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-olFXNWF6QRg/TsP7B1ZP1tI/AAAAAAAAAIY/I6SvEmJ_E2Y/s1600/connectToTFS01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="103" src="http://2.bp.blogspot.com/-olFXNWF6QRg/TsP7B1ZP1tI/AAAAAAAAAIY/I6SvEmJ_E2Y/s400/connectToTFS01.png" width="400" /></a></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">2. W kolejnym oknie naciskamy przycisk "Servers"</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-oGAtXeTFWvY/TsP7dHTEATI/AAAAAAAAAIg/aXmKVEKb8EI/s1600/connectToTFS02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="283" src="http://3.bp.blogspot.com/-oGAtXeTFWvY/TsP7dHTEATI/AAAAAAAAAIg/aXmKVEKb8EI/s400/connectToTFS02.png" width="400" /></a></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">3. Aby dodać połączenie do naszego serwera naciskamy przycisk "Add"</span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-MHufJAzl51M/TsP76b7OuzI/AAAAAAAAAIo/g0aRzxil58Q/s1600/connectToTFS03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="253" src="http://2.bp.blogspot.com/-MHufJAzl51M/TsP76b7OuzI/AAAAAAAAAIo/g0aRzxil58Q/s400/connectToTFS03.png" width="400" /></a></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">3. W popupie, który nam się pojawi wpisujemy adres naszego serwera (np. "testtutorialscrumitfs.no-ip.com"). I naciskamy OK. </span></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-CkcK02kC9m8/TsP8qbHPgBI/AAAAAAAAAIw/rJjLcblSiBg/s1600/connectToTFS04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="http://3.bp.blogspot.com/-CkcK02kC9m8/TsP8qbHPgBI/AAAAAAAAAIw/rJjLcblSiBg/s400/connectToTFS04.png" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">Jeżeli okno się bez problemów zamknie to znaczy, że nasza konfiguracja się powiodła. (Jeżeli pojawi się prośba o podanie loginu i hasło podajcie dane administratora systemu, na którym zainstalowany jest TFS)</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">Udało się? Gratuluję! </span></div>
<div style="text-align: justify;">
<span class="st" style="font-family: Verdana,sans-serif;">Jeżeli nie (odpukać), to piszcie szczegóły w komentarzach.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"> </span></div>
<span style="font-family: Arial,Helvetica,sans-serif;"> </span></div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-58020077740940369902011-11-11T13:06:00.001+01:002011-11-14T12:08:05.774+01:00Scrum i Team Foundation Server cz.2 - Instalacja TFS<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Tak jak zapowiedziałem w <a href="http://oskar-at-net.blogspot.com/2011/11/scrum-i-team-foundation-system-cz1.html" target="_blank">poprzednim wpisie</a>, część druga mojej opowieści o Scrum i TFS będzie opisywała instalację oraz wstępną konfigurację Team Foundation Server. Po tych wpisach powinno być wiadomo co chcemy robić oraz czym, część trzecia przedstawi jak.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Przykłady będą przedstawione na podstawie Team Foundation Server 11 Developer Preview.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><b><span style="font-size: large;"></span></b></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;"><b>Instalacja serwera TFS</b></span> </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">1. Pierwszym krokiem jest pobranie pliku instalacyjnego TFS 11 DP. Dostępny jest bezpłatnie pod adresem: </span></div>
<div style="text-align: left;">
<span style="font-family: Verdana,sans-serif;">- <a href="http://www.microsoft.com/download/en/details.aspx?id=27542#system-requirements" target="_blank">http://www.microsoft.com/download/en/details.aspx?id=27542#system-requirements</a></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">2. Po udanym pobraniu pliku uruchamiamy go. Pokaże nam się ekran:</span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-zr9W1HL85OE/Tr0Ua181mpI/AAAAAAAAACg/A5CP9rqdHYE/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="232px" src="http://3.bp.blogspot.com/-zr9W1HL85OE/Tr0Ua181mpI/AAAAAAAAACg/A5CP9rqdHYE/s320/01.png" width="320px" /></a></div>
<br />
<span style="font-family: Verdana,sans-serif;"> Akceptujemy licencję i naciskamy przycisk "Continue".</span><br />
<br />
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">3. W kolejnym ekranie zaznaczamy, że chcemy mieć włączone aktualizacje i rozpoczynamy proces instalacji naciskając przycisk "Install Now".</span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-dp4c0-Xd460/Tr0VcxopM4I/AAAAAAAAACo/BPAHgA1LeYQ/s1600/02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="231px" src="http://2.bp.blogspot.com/-dp4c0-Xd460/Tr0VcxopM4I/AAAAAAAAACo/BPAHgA1LeYQ/s320/02.png" width="320px" /></a></div>
<span style="font-family: Verdana,sans-serif;"></span><br />
<span style="font-family: Verdana,sans-serif;"> 4. Rozpocznie się proces kopiowania plików instalacyjnych.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/--ywcKop4oEo/Tr0XJEUNJmI/AAAAAAAAACw/rJ7YlXl9h6c/s1600/02b.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="235px" src="http://1.bp.blogspot.com/--ywcKop4oEo/Tr0XJEUNJmI/AAAAAAAAACw/rJ7YlXl9h6c/s320/02b.png" width="320px" /></a></div>
<br />
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">5. Po zakończeniu tego procesu pojawi nam się okno z wyborem rodzaju instalacji.</span></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-pktJfb0YvJA/Tr0ZUQh7lHI/AAAAAAAAAC4/xwCx4CA_uLM/s1600/03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="239px" src="http://1.bp.blogspot.com/-pktJfb0YvJA/Tr0ZUQh7lHI/AAAAAAAAAC4/xwCx4CA_uLM/s320/03.png" width="320px" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Dostępne są następujące tryby:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <b>Basic </b>- powinniśmy ją wybrać gdy chcemy mieć skonfigurowany system kontroli wersji, zarządzanie zadaniami oraz serwisy buildów. Wybór tej instalacji pozwala nam na wybranie istniejącej już bazy danych lub instalację SQL Express, gdy nie mamy żadnej bazy na komputerze. Jeżeli chcemy mieć skonfigurowanego Share Point lub Reporting Services powinniśmy wybrać inny tryb instalacji</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <b>Standard Single Server</b> - instalacja ta różni się od instalacji podstawowej tym, że konfiguruje również Share Point</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <b>Advanced </b>- mamy w niej dostęp do wszystkich opcji konfiguracyjnych. Pozwala m.in. na konfigurację TFSa do użytkowania zewnętrznych serwerów SQL, wybór instancji baz danych, Reporting Services oraz Share Point, użycie autentykacji Kerberos</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <b>Application-Tier Only</b> - pozwala na dodanie kolejnej instancji Team Foundation Server do istniejącego i skonfigurowanego środowiska</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">- <b>Upgrade </b>- pozwala na uaktualnienie aktualnej wersji Team Foundation Server</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Wybieramy instalację w trybie Basic i naciskamy przycisk "Start Wizard".</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">6. Pojawi się pierwszy ekran Basic Wizarda. Naciskamy w nim przycisk "Next"</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-IzYOkZPxw7M/Tr0eZFzUFRI/AAAAAAAAADA/BlZsV_XSgJY/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="239px" src="http://4.bp.blogspot.com/-IzYOkZPxw7M/Tr0eZFzUFRI/AAAAAAAAADA/BlZsV_XSgJY/s320/05.png" width="320px" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">7. Kolejny ekran pozwala na wybór czy chcemy zainstalować nową wersję bazy danych czy chcemy wybrać istniejącą instancję. W tym opisie zostanie zaprezentowana droga z zainstalowaną bazą danych. Zaznaczamy opcję "Use an existing SQL Server Instance" i naciskamy przycisk "Next".</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-_ipJZMgdO_U/Tr0fz36E--I/AAAAAAAAADI/nvlwjjVCvg0/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="239px" src="http://4.bp.blogspot.com/-_ipJZMgdO_U/Tr0fz36E--I/AAAAAAAAADI/nvlwjjVCvg0/s320/06.png" width="320px" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">8. W tym kroku powinniśmy wpisać nazwę instancji naszego serwera (w moim przypadku "WIN-MPMQ6E2DM0C"). Warto nacisnąć przycisk "Test", który sprawdzi, czy nasz serwer jest rzeczywiście dostępny, lub czy nie zrobiliśmy jakiejś literówki. Jeżeli po teście pojawi nam się zielona "fajka" możemy śmiało nacisnąć przycisk "Next".</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-7NAcpCafing/Tr0juN2rH5I/AAAAAAAAADY/BNhhvXEx3_0/s1600/08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240px" src="http://4.bp.blogspot.com/-7NAcpCafing/Tr0juN2rH5I/AAAAAAAAADY/BNhhvXEx3_0/s320/08.png" width="320px" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-U0HNTQI47-s/Tr0hrXoq9gI/AAAAAAAAADQ/gacAE1gFHF8/s1600/07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">9. Jeżeli wszystko przebiegło pomyślnie to powinien pojawić nam się ekran z podsumowaniem dotychczas dokonanych wyborów. Naciskamy przycisk "Next".</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-XvUsbrUoeQg/Tr0lXlIUptI/AAAAAAAAADg/ShvNfrU1s_I/s1600/09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240px" src="http://1.bp.blogspot.com/-XvUsbrUoeQg/Tr0lXlIUptI/AAAAAAAAADg/ShvNfrU1s_I/s320/09.png" width="320px" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">10. Następuje teraz proces intalacji/konfiguracji baz danych, serwera IIS oraz Firewalla. Po jego zakończeniu ekran powinien wyglądać:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-39UBx52k3RU/Tr0n8NeduqI/AAAAAAAAADo/jN2QNwCTD6g/s1600/11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="239px" src="http://2.bp.blogspot.com/-39UBx52k3RU/Tr0n8NeduqI/AAAAAAAAADo/jN2QNwCTD6g/s320/11.png" width="320px" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Naciskamy przycisk "Next".</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">12. W kolejny ekranie otrzymujemy jakże przyjemny napis "Success". Udało nam się zainstalować i skonfigurować pomyślnie TFS.</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-jWnRY6_5xeM/Tr0ooz6LKyI/AAAAAAAAADw/QdSir0BQsLY/s1600/12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="239px" src="http://2.bp.blogspot.com/-jWnRY6_5xeM/Tr0ooz6LKyI/AAAAAAAAADw/QdSir0BQsLY/s320/12.png" width="320px" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Naciskamy przycisk "Close".</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;"><b>Konfiguracja proxy TFS</b></span> </span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">13. Skoro udało nam się "</span><span style="font-family: Verdana,sans-serif;">zainstalować i skonfigurować pomyślnie TFS" to skąd kolejny punkt? OK, trochę nagiąłem prawdę. Co prawda TFS już stoi i ma się dobrze dokofigurujemy jeszcze dwie rzeczy. Proxy serwera, które pozwoli nam zmniejszyć obciążenie naszego serwera oraz serwisy Buildów. Wna głównym ekranie (przedstawionym w punkcie 5) na "Configure Team Foundation Server Proxy" . Powinien pojawić nam się ekran:</span></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-g30KAfeA6Jg/Tr0rqilRhfI/AAAAAAAAAEA/BUzdUmvlH7Q/s1600/14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="255px" src="http://4.bp.blogspot.com/-g30KAfeA6Jg/Tr0rqilRhfI/AAAAAAAAAEA/BUzdUmvlH7Q/s320/14.png" width="320px" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Naciskamy przycisk "Next".</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">14. Wybieramy użytkownika, przy pomocy którego proxy będzie łączyło się z TFS. Użytkownik ten powinien kontem serwisowym oraz zostać dodany do grupy użytkowników mających uprawnienia do TFS. Co prawda nie do końca bezpiecznie, ale dla ułatwienia wybrałem konto "NT AUTHORITY\LOCAL SERVICE". Po wyborze naciskamy przycisk "Next"</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-Ii1VEr5QdDk/Tr0tDmzU3WI/AAAAAAAAAEI/tQWy4gaVMdg/s1600/15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256px" src="http://2.bp.blogspot.com/-Ii1VEr5QdDk/Tr0tDmzU3WI/AAAAAAAAAEI/tQWy4gaVMdg/s320/15.png" width="320px" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">15. W kolejnym ekranie określamy port, na którym ma działać Proxy oraz miejsce, w którym ma być przechowywany jego Cache. Możemy pozostawić domyślne wartości oraz nacisnąć przycisk "Next".</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-vR8UFDoMS0Y/Tr0tn3m0cjI/AAAAAAAAAEQ/8Ky-P3EtyZE/s1600/16.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="243px" src="http://3.bp.blogspot.com/-vR8UFDoMS0Y/Tr0tn3m0cjI/AAAAAAAAAEQ/8Ky-P3EtyZE/s320/16.png" width="320px" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">16. Zobaczymy podsumowanie opcji, które wybraliśmy. Możemy zweryfikować ich poprawność naciskając przycisk "Verify" lub gdy ufamy sobie bezgranicznie nacisnąć od razu przycisk "Next".</span></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-lCQIecoTNmM/Tr0uEAob26I/AAAAAAAAAEY/I0CtJqCU7Ic/s1600/17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256px" src="http://3.bp.blogspot.com/-lCQIecoTNmM/Tr0uEAob26I/AAAAAAAAAEY/I0CtJqCU7Ic/s320/17.png" width="320px" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">17. Nastąpi proces sprawdzania konfiguracji i jeżeli wszystko poszło pomyślnie, wszystko zostanie oznaczone na zielono i będziemy mogli nacisnąć przycisk "Configure".</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-21wseh1kcms/Tr0uvBBt4QI/AAAAAAAAAEg/hGsuLDjoekA/s1600/18.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256px" src="http://2.bp.blogspot.com/-21wseh1kcms/Tr0uvBBt4QI/AAAAAAAAAEg/hGsuLDjoekA/s320/18.png" width="320px" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">18. Po udanej konfiguracji powinniśmy zobaczyć ekran:</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-xJGTGZTM_GM/Tr0vVLTAhHI/AAAAAAAAAEo/P__yP4v_EG4/s1600/19.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="255px" src="http://3.bp.blogspot.com/-xJGTGZTM_GM/Tr0vVLTAhHI/AAAAAAAAAEo/P__yP4v_EG4/s320/19.png" width="320px" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Naciskamy przycisk "Next".</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">19. Po raz kolejny możemy poczuć się dumni. Odnieśliśmy kolejny sukces - skonfigurowaliśmy proxy dla naszego serwera TFS. Po jego odtrąbieniu możemy zamknąć okno naciskając przycisk "Close"</span></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-mvrQw-OR7UU/Tr0wKOhXq9I/AAAAAAAAAEw/vg7Q0jvIJtU/s1600/20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="257px" src="http://3.bp.blogspot.com/-mvrQw-OR7UU/Tr0wKOhXq9I/AAAAAAAAAEw/vg7Q0jvIJtU/s320/20.png" width="320px" /></a></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: large;"><b>Konfiguracja serwisu Buildów</b></span> </div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
20. Tym razem darowałem sobie żart o zakończeniu procesu instalacji. Pozostało nam jeszcze bowiem skonfigurowanie serwisu Buildów. W głównym ekranie (patrz punkt 5) zaznaczamy "Configure Team Foundation Build Service" oraz naciskamy przycisk "Start Wizard". Pojawi nam się okno:</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-b3sAQlJKFxs/Tr0xjL2GDmI/AAAAAAAAAE4/koaYGVN0L5Y/s1600/23.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="239px" src="http://1.bp.blogspot.com/-b3sAQlJKFxs/Tr0xjL2GDmI/AAAAAAAAAE4/koaYGVN0L5Y/s320/23.png" width="320px" /></a></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
Jeżeli nie mamy na komputerze zainstalowanych innych serwerów TFS możemy bez zastanowienia nacisnąć przycisk "Next".</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<div style="font-family: Verdana,sans-serif; text-align: justify;">
21.
W kolejnym ekranie mamy możliwość wybrania liczbę "agentów buildów". Im
więcej ich mamy tym więcej buildów będzie mogło być naraz wykonywanych.
Należy wziąć jednak pod uwagę, że każdy proces budowania zużywa zasoby
systemowe, więc jeżeli nie mamy mocnego komputera nie ma sensu zwiększać
ich liczby. W tym tutorialu wybrałem rekomendowaną liczbę - 1. Po
wybraniu liczby agentów naciskamy przycisk "Next".</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-zruxFNfjlpY/TsAaB9VRI-I/AAAAAAAAAFA/sO-oC1LUZ-s/s1600/24.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="239" src="http://3.bp.blogspot.com/-zruxFNfjlpY/TsAaB9VRI-I/AAAAAAAAAFA/sO-oC1LUZ-s/s320/24.png" width="320" /></a></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
22.
Musimy wybrać również użytkownika, na którego koncie będzie działał
serwer buildów oraz port, na którym będzie łączył się z TFS. Ja wybrałem
systemowe konto "NT AUTHORITY\LOCAL SERVICE" oraz sugerowany port 9191.</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-KCW_oNU8irc/TsAbBo5n8-I/AAAAAAAAAFI/xHaYne7l32E/s1600/25.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/-KCW_oNU8irc/TsAbBo5n8-I/AAAAAAAAAFI/xHaYne7l32E/s320/25.png" width="320" /></a></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
Przycisk "Next" będzie standardowo dobrym wyjściem by przejść do kolejnego kroku.</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
23.
Pojawi się znany już nam ekran z podsumowaniem wybranych opcji. Jeżeli
jesteśmy dokonanych wyborów możemy śmiało nacisnąć "Next".</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-r65ni2n7dMM/TsAbjz-ainI/AAAAAAAAAFQ/ovsMz3m2gMg/s1600/26.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://3.bp.blogspot.com/-r65ni2n7dMM/TsAbjz-ainI/AAAAAAAAAFQ/ovsMz3m2gMg/s320/26.png" width="320" /></a></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
24.
Instalator przetestuje teraz czy wszystkie nasze ustawienia były
poprawne. Jeżeli wszystko przebiegnie bez problemów powinniśmy zobaczyć
ekran z przyjemnie zielonymi kolorami.</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Vjl2B7bEv_g/TsAcNFF8fMI/AAAAAAAAAFY/PwYokAa5uUQ/s1600/27.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="http://1.bp.blogspot.com/-Vjl2B7bEv_g/TsAcNFF8fMI/AAAAAAAAAFY/PwYokAa5uUQ/s320/27.png" width="320" /></a></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
Pozostaje nam tylko w następnym widoku nacisnąć przycisk "Configure".</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
25.
Nastąpi teraz instalacja i konfiguracja potrzebnych składników. Po jego
zakończeniu powinniśmy mieć wszystkie paski w kolorze zielonym tak jak
na screenie widocznym poniżej.</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-z0S5jOL1QKE/TsAeI8asgFI/AAAAAAAAAFg/9VHy20d5wmU/s1600/28.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="http://3.bp.blogspot.com/-z0S5jOL1QKE/TsAeI8asgFI/AAAAAAAAAFg/9VHy20d5wmU/s320/28.png" width="320" /></a></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
26.
Na koniec powinniśmy zobaczyć jakże miły napis "Success". Gdy już się
nim nacieszymy możemy nacisnąć przycisk "Finish" i zakończyć proces
konfiguracji.</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-H06rKxwrGIk/TsAec9LKzUI/AAAAAAAAAFo/Ig0PdxAShVs/s1600/29.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://3.bp.blogspot.com/-H06rKxwrGIk/TsAec9LKzUI/AAAAAAAAAFo/Ig0PdxAShVs/s320/29.png" width="320" /></a></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
Udało nam się zatem zainstalować Team Foundation System. Mamy już <a href="http://oskar-at.net/2011/11/scrum-i-team-foundation-system-cz1.html" target="_blank">wiedzę teoretyczną</a>, mamy narzędzie, w kolejnym wpisie dowiemy się jak z niego skorzystać.</div>
</div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"></span></div>
<span style="font-family: Verdana,sans-serif;"></span></div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-25718053847555862402011-11-09T22:34:00.000+01:002011-11-13T20:57:03.341+01:00Scrum i Team Foundation Server cz.1<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;"><b><span style="font-size: large;">1. Wstęp</span></b> </span><br />
<br />
<span style="font-family: Verdana,sans-serif;">W kilku najbliższych postach postaram się przybliżyć ideę zarządzania projektem w metodyce Scrum przy pomocy Team Foundation Server (TFS). W tym poście opiszę zasady i cechy jakimi charakteryzuje się SCRUM. W kolejnych przedstawię</span><span style="font-family: Verdana,sans-serif;"> jak TFS może nam pomóc w prowadzeniu projektu w tej metodyce. Ponieważ, mimo posiadanego doświadczenia </span><span style="font-family: Verdana,sans-serif;"> w niej</span><span style="font-family: Verdana,sans-serif;"> nie czuję się ekspertem będę bardzo rad z każdego, nawet najbardziej krytycznego komentarza, który pozwoli udoskonalić mi te wpisy. </span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br />
<b><span style="font-size: large;">2. Trochę historii</span></b></div>
<div style="text-align: justify;">
<br />
<span style="font-family: Verdana,sans-serif;">Pierwsze systemy komputerowe </span><span style="font-family: Verdana,sans-serif;">były zwykle </span><span style="font-family: Verdana,sans-serif;">tworzone dla organizacji rządowych, wojskowych lub dużych korporacji. Wszystkie one miały zwykle ściśle określone normy, przepisy, które miały cechować tworzone systemy. Dzięki temu można było sobie pozwolić na to, żeby przed powstaniem systemu przeprowadzić długą i kompleksową analizę biznesową, architektoniczną z tonami dokumentacji i dopiero po ukończeniu tego etapu wziąć się do prac programistycznych, a na samym końcu testerskich. Cykl życia tych projektów zwykle opierał się na <a href="http://pl.wikipedia.org/wiki/Model_kaskadowy" target="_blank">modelu kaskadowym</a> lub <a href="http://pl.wikipedia.org/wiki/Model_spiralny" target="_blank">modelu spiralnym</a>. Popularność zdobyły takie metodyki jak <a href="http://pl.wikipedia.org/wiki/PRINCE2" target="_blank">PRINCE2</a> lub <a href="http://pl.wikipedia.org/wiki/RUP" target="_blank">RUP</a>. Wraz z rozwojem komputerów osobistym oraz popularyzacją Internetu na przełomie XX i XXI wieku okazało się, że systemy informatyczne przestały być domeną dużych firm i organizacji - również małe i średnie przedsiębiorstwa zaczęły ich potrzebować. </span><br />
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Okazało się, że metody prowadzenia projektów dla dużych przedsiębiorstw nie koniecznie są dobre dla małych. Długotrwały proces analizy, bez żadnych widocznych efektów w postaci gotowych fragmentów był nie do zaakceptowania dla firm oczekujących szybkich efektów. Często okazywało się również, że mimo długiego etapu analizy po zakończeniu implementacji i testów wewnętrznych, klient mówił, że "on inaczej to sobie wyobrażał nie działa to tak jak powinno". Prowadziło to do zmian, które jak wiadomo im później są robione tym są bardziej czasochłonne, a co za tym idzie kosztowne.</span><br />
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Na przeciw tym zmieniającym się realiom wyszły metodyki zwinne (Agile). W 2001 roku został ogłoszony <a href="http://agilemanifesto.org/iso/pl/" target="_blank">Manifest Agile (Agile Manifesto)</a>, w którym m.in. Martin Fowler, Ken Schwaber określili ogólne zasady dla wszystkich metody z tej grupy. Oto one:</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<div style="text-align: center;">
<i><span style="font-family: Verdana,sans-serif;">"Wytwarzając oprogramowanie i pomagając innym w tym zakresie, </span></i></div>
<div style="text-align: center;">
<i><span style="font-family: Verdana,sans-serif;">odkrywamy lepsze sposoby wykonywania tej pracy. </span></i></div>
<div style="text-align: center;">
<i><span style="font-family: Verdana,sans-serif;">W wyniku tych doświadczeń przedkładamy: </span></i></div>
<div style="text-align: center;">
<i><span style="font-family: Verdana,sans-serif;">
Ludzi i interakcje ponad procesy i narzędzia. </span></i></div>
<div style="text-align: center;">
<i><span style="font-family: Verdana,sans-serif;">Działające oprogramowanie ponad obszerną dokumentację. </span></i></div>
<div style="text-align: center;">
<i><span style="font-family: Verdana,sans-serif;">Współpracę z klientem ponad formalne ustalenia. </span></i></div>
<div style="text-align: center;">
<i><span style="font-family: Verdana,sans-serif;">Reagowanie na zmiany ponad podążanie za planem. </span></i></div>
<div style="text-align: center;">
<i><span style="font-family: Verdana,sans-serif;">Doceniamy to, co wymieniono po prawej stronie, </span></i></div>
<div style="text-align: center;">
<i><span style="font-family: Verdana,sans-serif;">jednak bardziej cenimy to, co po lewej."</span></i></div>
<br />
<span style="font-family: Verdana,sans-serif;">Oprócz tego przedstawiono 12 zasad wytwarzania zwinnego oprogramowania (numeracja dodana przeze mnie):</span><br />
<div style="font-family: Verdana,sans-serif; text-align: center;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>"1. Najważniejsze dla nas jest zadowolenie Klienta</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>wynikające z wcześnie rozpoczętego i ciągłego dostarczania</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>wartościowego oprogramowania.</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>2. Bądź otwarty na zmieniające się wymagania</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>nawet na zaawansowanym etapie projektu.</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>Zwinne procesy wykorzystują zmiany</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>dla uzyskania przewagi konkurencyjnej Klienta. </i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>3. Często dostarczaj działające oprogramowanie</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>od kilku tygodni do paru miesięcy,</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>im krócej tym lepiej z preferencją krótszych terminów.</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>4. Współpraca między ludźmi biznesu i programistami</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>musi odbywać się codziennie w trakcie trwania projektu.</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>5. Twórz projekty wokół zmotywowanych osób.</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>Daj im środowisko i wsparcie,</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>którego potrzebują i ufaj im, ze wykonają swoją pracę.</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>6. Najwydajniejszym i najskuteczniejszym</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>sposobem przekazywania informacji do</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>i ramach zespołu jest rozmowa twarzą w twarz</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>7. Podstawową i najważniejszą miarą postępu jest działające oprogramowanie. </i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>8. Zwinne procesy tworzą środowisko do równomiernego</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>
rozwijania oprogramowania. Równomierne tempo</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>powinno być nieustannie utrzymywane poprzez sponsorów,</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>programistów oraz użytkowników.</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>9. Poprzez ciągłe skupienie na technicznej doskonałości</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>i dobremu zaprojektowaniu oprogramowania zwiększa zwinność.</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>10. Prostota – sztuka maksymalizacji pracy niewykonanej – jest zasadnicza.</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>11. Najlepsze architektury, wymagania</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>i projekty powstają w samoorganizujących się zespołach.</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>12. W regularnych odstępach czasu zespół</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>zastanawia się jak poprawić swoją efektywność,</i></div>
<div style="font-family: Verdana,sans-serif; text-align: center;">
<i>dostosowuje lub zmienia swoje zachowanie."
</i></div>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Verdana,sans-serif;">Te zasady stały są punktem wyjściowych dla metodyk Agile - w tym również dla Scrum. Jakie cechy ją charakteryzują? Dlaczego warto jej używać?</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-size: large;"><b><span style="font-family: Verdana,sans-serif;">3. Scrum</span></b></span><br />
<span style="font-family: Verdana,sans-serif;"> </span><br />
<span style="font-family: Verdana,sans-serif;">Jako się rzekło Scrum jest zwinną, <a href="http://pl.wikipedia.org/wiki/Model_przyrostowy" target="_blank">iteracyjną</a> metodyką. Jej nazwę zaproponował wymieniony już wcześniej Ken Schwaber. Uznał, że zasady gry w rugby świetnie obrazują to jak powinien wyglądać proces wytwarzania oprogramowania. Gra w rugby wygląda tak, że co jakiś czas następuje przerwa w grze, w której ustalany jest plan tego jak rozpocząć kolejną akcję, cała drużyna ustawia się w pozycję zwaną "młynem" (z ang. scrum). Rozpoczynana jest gra, występuje próba realizacji planu, aż do momentu zatrzymania gry. </span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://farm2.static.flickr.com/1427/1471251541_3188bf6684.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="http://farm2.static.flickr.com/1427/1471251541_3188bf6684.jpg" width="320" /></a></div>
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Dokładnie w ten sposób wygląda proces wytwarzania oprogramowania w metodyce Scrum. Cykl życia aplikacji podzielony jest na okresy zwane <b>sprintami</b>, w których występuje etap planowania, realizacji, podsumowania. No ale po kolei.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Elementy metodyki Scrum można podzielić na:</span><br />
<span style="font-family: Verdana,sans-serif;">- zespół (z podziałem na role),</span><br />
<span style="font-family: Verdana,sans-serif;">- zdarzenia,</span><br />
<span style="font-family: Verdana,sans-serif;">- artefakty,</span><br />
<span style="font-family: Verdana,sans-serif;">- reguły postępowania.</span><br />
<span style="font-family: Verdana,sans-serif;"><br />Wszystkie te elementy dają pełen obraz zasad, które kierują Scrumem. Zostaną one opisane w kolejnych punktach.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"><span style="font-size: large;"><b>4. Zespół Scrumowy</b></span></span><br />
<br />
<span style="font-family: Verdana,sans-serif;">W przeciwieństwie do metodyk "twardych" w Scrumie nie ma dużej ilości ról, zostały zdefiniowane tylko 3 role: </span><br />
<span style="font-family: Verdana,sans-serif;">- Właściciel Produktu,</span><br />
<span style="font-family: Verdana,sans-serif;">- Scrum Master</span><br />
<span style="font-family: Verdana,sans-serif;">- Zespół</span><br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-gKf2bYVJuWU/Trrnl3c7UjI/AAAAAAAAACI/JB_UN3649jg/s1600/team.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-gKf2bYVJuWU/Trrnl3c7UjI/AAAAAAAAACI/JB_UN3649jg/s1600/team.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><b style="font-family: Verdana,sans-serif; text-align: center;">Źródło:</b><span style="font-family: Verdana,sans-serif;"> Resnick, Steve; Bjork, Aaron; de la Maza, Michael (2011).<br /> Professional Scrum with Team Foundation Server 2010. Wiley</span></td></tr>
</tbody></table>
<br />
<br />
<span style="font-family: Verdana,sans-serif;"><b>4.1 </b><b>Właściciel Produktu</b> (Product Owner) - osoba będąca łącznikiem pomiędzy zespołem a klientem. Odpowiada za ustalenie wymagań biznesowych, nadanie im priorytetów oraz ocenę ich realizacji. Osoba ta kontaktuje się z klientem, ustala jego zapotrzebowania i oczekiwania.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;"><b>4.2 </b><b>Scrum Master </b>- odpowiada za to, żeby proces wytwarzania i oddawania produktu przebiegał płynnie i bez zakłóceń. Czuwa nad tym, żeby wszystkie zasady były stosowane, żeby członkowie zespołu mogli skupić się tylko na swoich zadaniach, nie byli rozpraszani, rzez inne nie będące w ich kompetencjach. Nie jest zalecane, żeby Scrum Master był również Właścicielem Produktu.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;"><b>4.3 </b><b>Zespół </b>(Team) - tutaj sytuacja jest bardziej zamglona i trudniejsza do określenia. Liczebność Zespołu powinna się wahać od 5 do 9 osób. Zgodnie z zasadami scrum, Zespół jest odpowiedzialny za utworzenie produktu. Każdy z członków zespołu <strike>jest sobie sterem, żeglarzem, okrętem</strike> powinien pełnić funkcje analityka, testera, programisty. Aby to było możliwe projekt powinien być prowadzony zgodnie z zasadami <a href="http://msdn.microsoft.com/pl-pl/library/test-driven-development.aspx" target="_blank">Test Driven Development (TDD)</a>, według których funkcjonalności</span><span style="font-family: Verdana,sans-serif;"> (szczególnie przepływy biznesowe)</span><span style="font-family: Verdana,sans-serif;"> powinny posiadać testy pozwalające na weryfikację ich działania.</span><br />
<br />
<span style="font-family: Verdana,sans-serif; font-size: large;"><b>5. Zdarzenia</b></span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Tak jak już wspomniałem wcześniej cykl wytwarzania produktu podzielony jest na Sprinty. <b>Sprint </b>jest najmniejszą jednostką czasową w scrumie. Każdy sprint jest zamkniętą całością. W jego obrębie następuje planowanie, realizacja i podsumowanie prac projektowych. Po jego zakończeniu powinna zostać dodana konkretna, weryfikowalna wartość biznesowa do projektu. </span><br />
<span style="font-family: Verdana,sans-serif;">Sprinty powinny trwać taki sam przedział czasu. Dzięki temu wprowadzona do projektu zostaje większa systematyczność. Pozwala to również lepiej określić jaki zakres pracy zespół jest w stanie wykonać podczas jednego Sprinta. Sugerowany czas trwania sprinta to od dwóch do pięciu tygodni.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Oprócz tego sprint cechują następujące zasady:</span><br />
<span style="font-family: Verdana,sans-serif;">- nie można dokonywać zmian mających wpływ na realizację celów sprintu,</span><br />
<span style="font-family: Verdana,sans-serif;">- nie można zmieniać składu Zespołu w trakcie sprintu,</span><br />
<span style="font-family: Verdana,sans-serif;">- nie można obniżać celów jakościowych,</span><br />
<span style="font-family: Verdana,sans-serif;">- czas zadań nie powinien się zmieniać. Kiedy jest jednak taka potrzeba to może to być dokonane tylko po konsultacjach pomiędzy Zespołem a Właścicielem Produktu.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;">W obrębie sprinta występują następujące zdarzenia:</span><br />
<span style="font-family: Verdana,sans-serif;">- codzienny scrum,</span><br />
<span style="font-family: Verdana,sans-serif;">- planowanie sprintu,</span><br />
<span style="font-family: Verdana,sans-serif;">- przegląd sprintu,</span><br />
<span style="font-family: Verdana,sans-serif;">- retrospektywa sprintu.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-Ikm4c122Zm4/TrrtI92-wQI/AAAAAAAAACY/tx2EdizgDdw/s1600/cycle.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-Ikm4c122Zm4/TrrtI92-wQI/AAAAAAAAACY/tx2EdizgDdw/s1600/cycle.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><b style="font-family: Verdana,sans-serif;">Źródło:</b><span style="font-family: Verdana,sans-serif;"> http://www.sadhanbiswas.com/myblog/techsavvy/agile-methodology/</span></td></tr>
</tbody></table>
<br />
<br />
<br />
<span style="font-family: Verdana,sans-serif;"><b>5.1 Codzienny scrum</b> jest spotkaniem Zespołu mającym na celu zrelacjonowanie postępów w realizacji zadań, pojawiających się problemów oraz przedstawienie swoich planów na najbliższy dzień pracy. Powinny one się odbywać z rana o jednakowej godzinie, nie trwać dłużej niż 15 minut na stojąco. Najlepiej w tym samym miejscu. Dlaczego na stojąco? Dla niewygody. Dzięki tej niezbyt przyjemnej do dyskusji pozycji zmniejszamy szansę na to, że osoby uczestniczące będą się rozwodziły bardziej nad swoimi rzeczami niż to konieczne. </span><br />
<span style="font-family: Verdana,sans-serif;">Ważne jest również to, że w trakcie Codziennego Scruma nie rozwiązujemy problemów, relacjonujemy je i ewentualnie ustalamy, czy jest ktoś kto ma pomysł na jego rozwiązanie.</span><br />
<span style="font-family: Verdana,sans-serif;">Scrum Master na tych spotkaniach odgrywa rolę moderatora.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;"><b>5.2 Planowanie sprintu</b> odbywa się jak można się łatwo domyśleć na początku sprintu. Określane w nim jest to co ma zostać wykonane w jego obrębie. Nie powinno ono trwać dłużej niż 8h dla sprintu 4 tygodniowego, 4h dla dwutygodniowego.</span><span style="font-family: Verdana,sans-serif;"> </span><br />
<span style="font-family: Verdana,sans-serif;">Pierwszym etapem planowania jest wybranie z pośród puli zadań dla całego projektu (zwanym Rejestrem Produktu lub z ang. Product Backlog) tych które zostaną w nim wykonane (zadania te zostają wrzucone do puli zwanej Rejestrem Sprintu lub z ang. Sprint Backlog). Odbywa się on poprzez dialog Zespołu z Właścicielem Produktu. Oszacowany zostaje również wstępny czas jaki jest potrzebny na zrobienie danego zadania. </span><br />
<span style="font-family: Verdana,sans-serif;">Przy wyborze zadań do Sprintu powinny być brane pod uwagę takie czynniki jak:</span><br />
<span style="font-family: Verdana,sans-serif;">- liczebność zespołu,</span><br />
<span style="font-family: Verdana,sans-serif;">- analogie z poprzednimi sprintami, porównanie ile udało się w nich zrobić,</span><br />
<span style="font-family: Verdana,sans-serif;">- oraz to, żeby zadania składały się w logiczną całość, tak, żeby po zakończeniu Sprintu została oddana konkretna wartość biznesowa.</span><br />
<span style="font-family: Verdana,sans-serif;">Określony zostaje również <b>Cel Sprintu</b>. Jest nim zwykle kamień milowy w obrębie danego produktu np. utworzenie konkretnego modułu, funkcjonalności. </span><br />
<span style="font-family: Verdana,sans-serif;">W drugiej części planowania Zespół określa szczegóły implementacji wybranych zadań. Dekomponuje je na podzadania, tak aby odzwierciedlały one lepiej etapy programistyczne konieczne do ich wykonania. Weryfikowane są również poprzednie szacunki czasów wykonania zadań. Możliwa jest też zmiana zawartości Rejestru Sprintu, ale tylko i wyłącznie po konsultacji i akceptacji Właściciela Produktu.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"><b>5.3 Przegląd Sprintu</b> - jest to podsumowanie dokonywane na zakończenie Sprintu. Ustalane jest na nim co się udało a co się nie udało zrobić. Określone zostaje jak duży był Przyrost (Effort) wykonany w trakcie Sprintu. Omawiane zostają również problemy na jakie natrafiono w trakcie realizacji zadań. Zadania, które nie zostały zrealizowane wracają do Rejestru Produktu.</span><br />
<span style="font-family: Verdana,sans-serif;">Zwykle odbywa się prezentacja aktualnej wersji produktu dla Właściciela Produktu, który jest osobą akceptującą realizację zadań. Określana jest też wstępna wizja tego co będzie działo się w kolejnym Sprincie.</span><br />
<span style="font-family: Verdana,sans-serif;">Przegląd nie powinien trwać dłużej nić 4 godziny dla Sprintu 4 tygodniowego i 2 godziny dla 2 tygodniowego.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"><b>5.4 Retrospektywa Sprintu</b> - Odbywa się ona po przeglądzie. Jest to chwila, w której Zespół może przeanalizować to co dobrego/złegoT wydarzyło się w ostatnim Sprincie. Zespół powinien określić co i jak można było by poprawić, które działania, metody należało by kontynuować. Zadaniem Scrum Mastera jest przeprowadzić tak dyskusję, żeby każdy z członków zespołu aktywnie brał udział w opracowywaniu nowych zaleceń.</span><br />
<span style="font-family: Verdana,sans-serif;">Spotkanie to nie powinno trwać dłużej niż 3 godziny.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<b><span style="font-family: Verdana,sans-serif; font-size: large;">6. Artefakty</span></b><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Artefakty są to elementy, które opisują wykonywaną pracę wykonywaną podczas trwania projektu w Scrumie. Są to:</span><br />
<span style="font-family: Verdana,sans-serif;">- Rejestr Produktu (Product Backlog),</span><br />
<span style="font-family: Verdana,sans-serif;">- Rejestr Sprintu (Sprint Backlog),</span><br />
<span style="font-family: Verdana,sans-serif;">- Przyrost (Effort)</span><br />
<br />
<span style="font-family: Verdana,sans-serif;"><b>6.1</b> </span><span style="font-family: Verdana,sans-serif;"><b>Rejestr Produktu - </b>j</span><span style="font-family: Verdana,sans-serif;">est to zbiór wymagań, zmian oraz zadań, które muszą zostać wykonane, żeby produkt został utworzony w całości. Zadania te są zwykle w postaci Historii Użytkownika (User Stories), czyli opisu tego jakie ma być zachowanie systemu w kontakcie z użytkownikiem. Każda historia użytkownika powinna zawierać kryteria akceptacji jego realizacji.</span><br />
<span style="font-family: Verdana,sans-serif;">Za zarządzanie i pielęgnację Rejestru Produktu odpowiada Właściciel Produktu. Rejestr Produktu ewoluuje wraz z produktem. Na podstawie kontaktów z użytkownikami, pracami Zespołu w trakcie sprintów pojawiają się uwagi, doprecyzowania, zmiany, błędy. Rejestr Produktu pozostaje pusty dopiero gdy nie będą dokonywane żadne prace nad produktem.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;"><b>6.2 Rejestr Sprintu</b> - w trakcie realizacji produktu, wraz z kolejnymi Sprintami przenoszone zostają elementy z Rejestru Produktu do Rejestrów kolejnych Sprintów. Wszystkie te elementy wchodzą w skład zdefiniowanego celu dla danego sprintu. Ponieważ Historie Użytkownika nie są wystarczająco precyzyjną formą opisu zadań dla Zespołu, zwykle dzielone są na podzadania, wg logicznego programistycznego podejścia.</span><br />
<span style="font-family: Verdana,sans-serif;">Jedynie Zespół może zadecydować o dodaniu czegoś lub usunięcia z Rejestru Sprintu. Po zakończeniu Sprintu Zespół wraz z Właścicielem Produktu decydują co zrobić z niezrealizowanymi historiami użytkowników (czy je zamknąć czy wrzucić z powrotem do Rejestru Produktu).</span><br />
<br />
<span style="font-family: Verdana,sans-serif;"> </span><br />
<span style="font-family: Verdana,sans-serif;"><b>6.3. Przyrost</b> - jest to wskaźnik, mówiący o tym co do tej pory udało się zrealizować. Każda historia użytkownika jest opisana przez punkty przyrostu. Poprzez sumę przyrostów poszczególnych Historii Użytkownika wyrażona jest ilość zrealizowanych funkcjonalności.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Ufff. Trochę się spisałem, a i tak wydaje mi się, że póki co przeskoczyłem tylko po łebkach przez tematy związane ze Scrumem. W kolejnych wpisach przedstawię jak Team Foundation Server może nam pomóc w codziennej pracy ze Scrumem, jak ją ułatwić i pozwolić sprawnie go prowadzić.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;">Tak jak wspominałem proszę Was gorąco o uwagi co do niejasności/błędów/zamglonych opisów.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<span style="font-family: Verdana,sans-serif;"><a href="http://oskar-at-net.blogspot.com/2011/11/scrum-i-team-foundation-server-cz2.html" target="_blank">Kolejny wpis</a> to instalacja i wstępna konfiguracja TFS.</span><br />
<span style="font-family: Verdana,sans-serif;"><br /></span><br />
<br />
<b><span style="font-family: Verdana,sans-serif;">Źródła:</span></b><br />
<span style="font-family: Verdana,sans-serif;">- </span><span style="font-family: Verdana,sans-serif;">Resnick, Steve; Bjork, Aaron; de la Maza, Michael (2011). Professional Scrum with Team Foundation Server 2010. Wiley <a href="http://www.amazon.com/Professional-Scrum-Foundation-Server-Programmer/dp/0470943335" target="_blank">[Amazon]</a></span><br />
<span style="font-family: Verdana,sans-serif;">- Schwaber, Ken; Sutherlanda, </span><span style="font-family: Verdana,sans-serif;">Jeff (2011) - The Scrum Guide <a href="http://www.scrum.org/scrumguides/" target="_blank">[Link]</a></span><br />
<span style="font-family: Verdana,sans-serif;">- Agile Manifesto (2001) - <a href="http://agilemanifesto.org/" target="_blank">[Link]</a></span></div>
</div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com6tag:blogger.com,1999:blog-8979460837090429655.post-78932590610530245142011-10-17T14:57:00.000+02:002011-10-17T15:18:31.294+02:00Ciekawostki cz. 1<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="font-family: Verdana,sans-serif;">
Dzisiaj będę się chwalił się swoją niewiedzą. Kilka dni temu kolega zadał mi pytanie, którym skutecznie mnie zagiął. Ponieważ uważam, że głupotą nie jest brak wiedzy co raczej udawanie, że się ją posiada, czym prędzej się Wam tym pytaniem chwalę. </div>
<div style="font-family: Verdana,sans-serif;">
<b><br /></b></div>
<div style="font-family: Verdana,sans-serif;">
<b>Co zostanie wyświetlone po takim kodzie i dlaczego? </b></div>
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">string string1 = "Test";
string string2 = string1;
string string3 = "Test";
Console.WriteLine(Equals(string1, string2)); // 1.
Console.WriteLine(Equals(string1, string3)); // 2.
Console.WriteLine(ReferenceEquals(string1, string2)); //3.
Console.WriteLine(ReferenceEquals(string1, string3)); //4.
</pre>
<br />
<div style="font-family: Verdana,sans-serif;">
<b>Odpowiedź </b><br />
<a href="javascript:FUnHide('ciekawostkicz1odpowiedz')">(Pokaż)</a></div>
<div id="ciekawostkicz1odpowiedz" style="display: none; font-family: Verdana,sans-serif;">
Pierwsze i drugie porównanie pokażą oczywiście <b>true </b>- Equals porównujący stringi o tej samej wartości zawsze pokaże <b>true</b><br />
<br />
Drugi i trzeci pokażą również <b>true</b> - tutaj był mój błąd. Uznałem, że skoro string nie jest typem referencyjnym to przy przepisaniu skopiuje on wartość, a nie przepisze referencję. W teorii tak powinno być, ale w tym momencie do gry wchodzi <b>Optymalizator</b> <b>Kompilacji</b>. Ten byt czuwa nad tym, aby nasz program działał jak najszybciej maskując ile się da nasze błędy. W tym przypadku zauważył, że nie ma sensu tworzyć nie wiadomo ile obiektów, skoro i tak string ma przeładowaną metodę Equals i operatoror porównywania. Zamiast generować kolejne obiekty poprzypinał on referencje do jednego obiektu.<br />
Optymalizator jest na tyle sprytny, że potrafi się obronić przed takimi trikami:<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">string string4 = string1 + String.Empty;
Console.WriteLine(ReferenceEquals(string1, string4));
</pre>
Dla powyższego kodu również wyświetli true.<br />
Dopiero coś takiego potrafi go wprawić w konsternację i każe mu wyświetlić upragniony <b>false</b>:<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">string string5 = (string3 + "a").Replace("a", String.Empty);
Console.WriteLine(ReferenceEquals(string1, string5));
</pre>
<a href="javascript:FHide('ciekawostkicz1odpowiedz')">(Ukryj)</a>
</div>
<div style="font-family: Verdana,sans-serif;">
<br /></div>
</div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com5tag:blogger.com,1999:blog-8979460837090429655.post-48082980361158106142011-10-06T21:54:00.000+02:002011-10-06T21:54:59.066+02:00Błąd "Cannot update a parent row: a foreign key constraint fails" przy pobieraniu rekordów w NHibernate<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="font-family: Verdana,sans-serif;">
Dzisiaj kolejny krótki wpis, ponownie dotyczący NHibernate'a.<br />
Jak pewnie zdążyliście zauważyć jest to coś co ostatnio sprawia mi najwięcej problemów.</div>
<div style="font-family: Verdana,sans-serif;">
Próbując pobrać rekordy przy pomocy zwykłego selecta zawężonego o kryteria w NHibernate, otrzymałem zaskakujący błąd </div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">"Cannot update a parent row: a foreign key constraint fails"</pre>
<div style="font-family: Verdana,sans-serif;">
Pierwsza moja myśl była: "Pobieram rekordy, a on chce robić update? Jak to, zgłupiał?!".<br />
Miałem klasę zdefiniowaną jako:<br />
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public class KontoBankowe
{
public virtual int Id { get; set; }
public virtual int Oprocentowanie { get; set; }
public virtual int IdBanku { get; set; }
}
</pre>
oraz mapowanie klasy jako:<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public class KontoBankoweMapowanie : ClassMap<KontoBankowe>
{
public KontoBankoweMapowanie()
{
Table("KontoBankowe");
Id(e => e.Id);
Map(e => e.Oprocentowanie, "Nazwisko").Not.Nullable();
Map(e => e.IdBanku , "IdBanku ");
}
}
</pre>
<br />
Widzicie już co jest źle? Jeżeli tak, to bardzo Wam gratuluję, bo mnie to chwilę zajęło.<br />
Dla równie opornych na wiedzę jak ja, tłumaczenie:<br />
1. Pobieramy wiersze konta bankowego.<br />
2. Wśród rekordów mamy wiersze, które w kolumnie <b>IdBanku</b> mają <b>nulle</b> (tabela i mapowanie na to pozwalają).<br />
3. Po pobraniu nulla NHibernate ustawia wartość właściwości <b>IdBanku</b> klasy <b>KontoBankowe</b> jako domyślna wartość typu <b>int</b>, czyli <b>0</b>.<br />
4. Ponieważ encja pobrana przez nas jest różna od tej, która jest w bazie (<b>0</b>, zamiast <b>null</b>) to NHibernate przy wywołaniu metody Session.Flush() próbuje uaktualnić pobrany rekord. Nie istnieje, żaden bank o id równym 0, więc update wyrzuca błąd na kluczu obcym łączącym tabelę <b>KontoBankowe</b> z tabelą <b>Bank</b>.<br />
<br />
Rozwiązanie problemu jest proste. Wystarczy w klasie <b>KontoBankowe</b> ustawić pole <b>IdBanku</b> jako <b>int ?</b>. Po poprawkach klasa będzie wyglądała:<br />
<br />
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">public class KontoBankowe
{
public virtual int Id { get; set; }
public virtual int Oprocentowanie { get; set; }
public virtual int ? IdBanku { get; set; }
}
</pre>
<br />
Do zapamiętania: <b>Zawsze sprawdzać czy ustalone pole jako nullable jest typem, który może przyjąć wartości null (ze szczególnym uwzględnieniem typów prostych i struktur)</b>.<br />
<br /></div>
</div>
Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0tag:blogger.com,1999:blog-8979460837090429655.post-85406260665674550432011-10-01T15:19:00.000+02:002011-11-11T13:14:58.180+01:00Jak odblokować workspace w TFS<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="font-family: Verdana,sans-serif; text-align: justify;">
Dzisiaj kolejny przykład z życia wzięty, krótszy ale miejmy nadzieję, przydatny.
Zmieniłem na swoim komputerze nazwę grupy roboczej, do której należę. Po uruchomieniu Visual Studio i próbie checkoutu pliku okazało się, że pojawił mi się komunikat o błędzie:</div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">A local workspace is required.
Workspace NazwaGrupyRoboczej;Nazwa użytkownika
does not reside on this computer.
</pre>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
Komunikat ni mniej ni więcej mówi, że VS nie mogło odnaleźć wcześniejszego workspace'a. Powodem jest to z tego, że TFS cache'uje workspace'y. Jak zatem wymusić na żeby odświeżył je i zobaczył naszą zmianę?</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
Należy uruchomić Visual Studio Command Prompt (Start => Programy => Microsoft Visual Studio 2010 => Visual Studio Tools => Visual Studio Command Prompt (2010)) i wpisać w nim:</div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<pre class="brush: csharp; " name="code" style="font-family: Verdana,sans-serif;">tf workspaces /s:URLDoTwojegoSerweraTFS
</pre>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
I już.</div>
</div>Oskar Dudyczhttp://www.blogger.com/profile/10785228175797214910noreply@blogger.com0