• This is a usual time of the year for summaries so let’s keep the tradition alive and write one. Here’s my 2017 achievements split between months. January Blogging for 18 days straight – nothing near gutek’s achievement (whole year!) but still a nice streak Microsoft MVP title (thx Konrad Kokosa for pointing this one ;)) February […]

  • “Advent of Code is a series of small programming puzzles for a variety of skill levels.” Each day was a fun an interesting coding challenge. I’ve decided to practice and code this in python to learn the skill. Some of them might not be the best python scripting as I was short on time in […]

  • Some time ago I’ve attended a .net developer days 2017 conference. I was quite busy since (traveling, teaching .net, working) that only now I got some time to share some thoughts about it. As a bonus I’m including a short interview I did during the event. I need to state here, just to be clear, […]

  • We developers don’t like documentation. We don’t like to read it, and we even more we don’t like to write it. But sometimes it is worth to read it. Like when you find out that by using datetime in SQL DB you got a milliseconds precision but only if it ends on 0,3,7 (link). That […]

  • In the previous post we’ve removed some of the technical debt that could be found in our NetDeveloperPoland Website application. In this one we will remove it even more. We can even maybe reach a B? Let’s see where we’ll end up at the end of this part.

Nie, nie… dziś nie będzie o daktyloskopii a o odciskach palca dla certyfikatów. Jak wiemy (albo i nie wiemy) certyfikat każdy posiada skrót (‘odcisk palca’), który unikalnie go identyfikuje (jak w życiu :)). Niedawno miałem potrzebę znalezienie takowego certyfikatu po takowym odcisku. Wygooglałem MSDNa i znalazłem potrzebną mi funkcję – Find.

var store = new X509Store(storeName, storeLocation);
store.Open(OpenFlags.ReadOnly);
var coll = store.Certificates.Find(findType, findValue, true);                                
if (coll.Count < 1)
{
    throw new ArgumentException(“Unable to locate certificate”);
}

Zapodałem jej odpowiednie argumenty, jako findType ustawione FindByThumbprint, jako findValue – odcisk. Uruchamiam i bum. Wyjątek. Sprawdzam raz jeszcze odcisk. Zgadza się. Wyjątek dalej. Sprawdzam bajt po bajcie i znów to samo! Kolejne WTF leci pod nosem…

Rozwiązanie (a przynajmniej naprowadzenie na trop) pojawia się w głowie gdy zajrzymy sobie do metody Find… pomiędzy innymi rzeczami zobaczymy taki oto kawałek kodu

byte[] managed = X509Utils.DecodeHexString((string) findValue);

Czyli nasz odcisk jest zamieniany na bajty przed porównaniem…a skoro bajty to może kodowanie znaków?Może ono ma coś do czynienia tutaj? Przepuśćmy nasze findValue przez prostą metodę konwertującą UTF8 do ASCII. Po takiej prostej operacji widzimy, że na początku poza znakami ASCII mamy powtarzającą się dwukrotnie sekwencję – E2 80 E8
Szybkie zerknięcie na tabelkę kodów UTF8 i wszystko jasne. LEFT-TO-RIGHT marker – niewidoczny znacznik, który powodował, że porównanie odcisków skutkowało niemożliwością prawidłowego znalezienia certyfikatu…wystarczyło skasować odcisk (ważne – wraz z ” “)…napisać go jeszcze raz i działa. Taki mały upierdliwiec zabierający 2-3h z życiorysu…

Nauczka na przyszłość, aby nie kopiować kodu ze strony WWW 🙂


dotnetomaniak.plNajciekawsze artykuły o .NET


W ostatnią środę miałem przyjemność wygłosić swoją prezentację o Mono.Cecil na Krakowskiej Grupie Developerów .NET (KGD.NET). W stosunku do prezentacji na Wroc.NET postanowiłem dodać przykład pokazujący problem wczytania biblioteki z Framework’a 1.1 w aplikacji napisanej w 4.0 za pomocą System.Reflection (czemu tak się dzieje pozostaje otwarte, ale być może poruszę ten temat w innym wpisie).

W celu zaprezentowania tego posłużyłem się banalnym przykładem, który zmodyfikowałem aby wczytywał bibliotekę z .net 4.0 w celu wyjaśnienia odmienności działania. Zmodyfikowany kod wyglądał jak poniżej:

            const string assemblyName = @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Design.dll";
            Assembly netReflection = Assembly.LoadFile(assemblyName);
            var types = netReflection.GetTypes().ToArray();
            Console.WriteLine("Types in assembly: {0}",types.Length);

            var mono = AssemblyDefinition.ReadAssembly(assemblyName);
            var monoTypes = mono.Modules.Select(x => x.GetTypes());
            Console.WriteLine("Types in assembly: {0}", monoTypes.Sum(x => x.Count()));
Niby nic nadzwyczajnego a wynik zaskoczył, bowiem po uruchomieniu na ekranie pojawił się następujący rezultat.
Zagwozdka…
Pierwszy wynik to z System.Reflection, drugi – z Mono.Cecil. Podczas prezentacji drążyć tematu nie mogłem (przykład był kodowany w trakcie sesji Gosi :)) ale oczywiście wrodzona ciekawość nie pozwoliła mi tak zostawić tego tematu. Dziś znalazłem chwilę i po małej zmianie kodu i kilku operatorów LINQ byłem w posiadaniu listy wszystkich typów do porównania.
Po wrzuceniu w difftool’a długi szukać nie musiałem, bo oto w zasadzie przy samym początku mamy różnicę (powiększenie po kliknięciu w zdjęcie):

Mono.Cecil zwrócił jako typ czego nie uświadczymy w liście z System.Reflection. Ciekawe kto tutaj ma rację. Można popatrzeć w źródła dlaczego tak się dzieje…być może, jak kiedyś czas pozwoli, zbadam temat dokładniej…na chwilę obecną miejcie na uwadze tę różnicę.


dotnetomaniak.plNajciekawsze artykuły o .NET


Często można przeczytać, że Javascript to język assemblera dla sieci. Porównanie to jest dość dobre, bo w JS podobnie jak w ASM pisze się ciężko (choć nie tak jak w asm :-)) a dodatkowo ogólny brak dobrych narzędzi do debuggowania, testowania etc. (od razu napiszę, że brak to nie znaczy, że nie ma).

Od dziś do mojego pasa narzędziowego zostało dodane nowe, fajne narzędzie. Visual Event 2 to prosty skrypt który pozwoli nam podejrzeć jakie eventy są przypięte do których elementów na stronie. Często tego właśnie mi brakowało, żeby dowiedzieć się czemu jakieś zdarzenia nie wykonują się tak jak powinny.

Visual Event w akcji.

Dla wszystkich robiących cokolwiek z użyciem JS będzie to pewnie jedno z niezastąpionych narzędzi w przeglądarce.

Miłego kodowania.

Wow….jak patrzę na datę ostatniego postu to, aż mi żal, że przez taki długi okres nic nie napisałem. Nie to, że nie było pomysłów – kilka postów w zanadrzu jest.

“Niestety” duża ilość projektów firmowych i innych sprawiło, że bloga trzeba było odłożyć na później. Jak tak dalej pójdzie trzeba będzie na poważnie poszukać współpracowników 🙂
Nawet post z podsumowaniem 2012 roku nie znalazł się na blogu z podobnych powodów. Z drugiej strony przeszło mi publiczne podsumowywać co się udało a co nie – zbyt duże obciążenie psychiczne :). Wnioski dla mnie wysnute i zobaczymy co będzie w 2013.

Plany na przyszły rok podobne jak poprzednio – zwiększenie przychodów firmy i rozwój techniczny. Liczę, że jednak więcej czasu będę miał na bloga i więcej ciekawych postów na nim się znajdzie. Kilka pozatechnicznych “projektów” w planach jest również ;).
Będę kontynuował działanie we WrocNET i być może kilka razy pojawię się na zaprzyjaźnionych grupach z jakąś prezentacją (zacznę w styczniu na KGD.NET).

Pomyślnego 2013 roku. Prywatnie i zawodowo! Oby było lepiej niż w 2012 🙂

Dziś będzie trochę wspomnień, ewentualnie historii. Postanowiłem bowiem napisać o moim pierwszym komputerze. Jeśli nudzą się melancholijne wywody z przeszłości – nie czytaj dalej. Jeśli jednak lubisz stary sprzęt i z miłą chęcią wracasz do czasów swojego 8-bitowca. Zapraszam.


U mnie wszystko zaczęło się około roku 1989 kiedy to w domu pojawiła się mała, czarna skrzyneczka. U góry miała napisana Timex Computer 2048 i wyglądała jak poniżej:

Wikipedia

Nie było wielkiego pudła i huczącego wentylatora. Nie było monitora bo podłączało się toto bezpośrednio do telewizora. Miał zamiast tego fajny żółty magnetofon i joystick!

Całą magia siedziała w pudełku z klawiaturą, która to sama w sobie była całkiem niezłym orzechem do zgryzienia. Każdy klawisz miał kilka funkcji/znaczeń w zależności od trybu. I tak naciskając klawisz P mogliśmy uzyskać: ‘P’, ‘PRINT’ ,'”‘, TAB lub ©. Trzeba było się tego nauczyć bo inaczej było kiepsko. Wgranie programu to była sztuka :). Trzeba było ustawić kasetę w okolicach początku danej gry, wpisać LOAD “NAZWA GRY” wdusić Enter i włączyć magnetofon. Trzymanie kciuków i wychodzenie z pokoju były na porządku dziennym. Czego się nie robiło, aby pograć w Commando czy Bomb Jack. Późniejsze etapy wgrywania to podziwianie kolorowych pasków – takich jak na zrzutach poniżej:

Jak wszystko się udało, to po kilku minutach (tak minutach!) można było cieszyć się ulubioną grą. Bomb Jack raczył nas takim gameplay’em a Commando takim. Ehh te popsute Joysticki od naciskania fire :).

Na maszynie tejże liznąłem też pierwsze podstawy programowania (a w zasadzie przepisywania kodu z książki i jego modyfikowania – :). Takie oto cuda można tam znaleźć – rozdział 20 – Kolory

    5 REM PROGRAM - KOLORY
10 FOR X=0 TO 7
20 BORDER X:PAUSE 30: NEXT X
30 GOSUB 5000
40 FOR Z=1 TO 3: GOSUB Z*1000
50 NEXT Z
60 GOSUB 5000
1000 INVERSE 1: GOSUB 5000
1010 RETURN
2000 INVERSE 0: FLASH 1: GOSUB 5000
2010 RETURN
3000 FLASH 0: BRIGHT 1: GOSUB 5000
5000 FOR Y=0 TO 7: PAPER Y
5010 PRINT INK 9;"TIMEX COMPUTER 2048"
5020 PAUSE 30: NEXT Y
5030 PRINT
5040 RETURN

Cud miód. Nie wiem czemu, ale ciągle mam sentyment do tego sprzętu i postanowiłem go uruchomić :). Udało się zdobyć gdzieś na aukcjach sprzęt (mój niestety nie dotrwał do czasów obecnych – Rest In Pieces :)), ale to było już sporo temu i sprzęt trochę zaczął się kurzyć. Ostatnie miesiące to już jednak mocne postanowienie poprawy i narodziła się akacja reaktywacja.
Niestety, na przeszkodzie stanął brak telewizora (a co – hipster jestem :]), ale to dało się obejść z pomocą Tunera TV. Jeszcze tylko mały problem ze spalonym zasilaczem i można było działać. Kompletny zestaw poniżej:

Jak widać brakuje mojego żółtego magnetofonu, ale walkman daje radę. Przydałby mu się licznik obrotów, bo mam czasem problem z ustaleniem gdzie dana gra się zaczyna :), Można trochę poprzewijać, poszukać i nie jest źle. W sumie czego się nie robi, żeby sobie przypomnieć lata młodzieńcze. Teraz pozostaje tylko zdobyć kasetę z Bomb Jack’iem i Commando. A jak już się mi znudzą to może powyciągam trochę taśmy z kaset i zacisnę w dłoń jakiś ołówek :)? (link)

Jakby ktoś chciał sobie poczytać – trochę więcej informacji o sprzęcie na zxspectrum.pl oraz na Wikipedii.

A wy jak wspominacie swoje pierwsze “miłości” IT?

by Shane Pope

W 2010 roku poczyniłem post prezentujący być może jedną z mniej znanych funkcji Visual Studio 2010. Jako, że od tamtego czasu minęło sporo czasu a za nami release najnowszej wersji VS postanowiłem odświeżyć tamten wpis co nieco.
Klawiatura w życiu programisty jest ważna. To tu nasze ręce spoczywają przez większość dnia, to tu gromadzimy zapasy jedzenie na zimę i to tędy przelewamy naszą wiedzę na papie…eeekran. Myszka jest drugorzędna. Przydaj się tylko, aby zrobić jakąś dodatkową czynność i powrócić do stukania w klawisze. Dlatego tak istotna powinna być dla każdego programisty umiejętność obsłużenia się w naszym IDE bez potrzeby mozolnej czynności przekładania dłoni z klawiatury na myszkę.

“Niestety” edycja 2012 pozbawiła nas FindBox’a i możliwości użycia go do sprawnego poruszania się po zakamarkach Visual Studio, ale dała nam jeszcze mocniejsze narzędzie – Quick Launch’a.

Tym razem twórcy naszego IDE podpisali kontrolkę, tak aby już nikt nie miał problemów z tym jak się ona nazywa. Z Find Box’em zawsze były problemy, że nie zawsze wiadomo było o które pole chodzi :). Od razu dowiadujemy się też skrótu klawiszowego, który pozwoli nam dostać się do tego

Quick Launch daje nam dość pokaźne możliwości w przeszukiwaniu Visual Studio i otwartego projektu.

Okienko to pozwala na przeszukanie kilku źródeł danych. Z pudełka dostępne są: @menu, @mru, @opt, @doc. Ich dostępnością możemy sterować za pomocą ustawień. Jeśli, któreś źródło nam nie jest potrzebne – możemy je wyłączyć. Jeśli w ogóle nie korzystamy z tego dobrodziejstwa – też możemy je wyłączyć totalnie. Możemy także zastosować te filtry aby ograniczyć ilość zwracanych informacji. Czasem przydatne jeśli od razu wiemy, że potrzebujemy opcji w ustawieniach.

Można także dodawać swoje własne źródła. W jednym z najbliższych postów postaram się pokazać jak można to zrobić.

Z innych ciekawych “trików” czy wiedzieliście, że w VS wciskanie ESC wielokrotnie w końcu doprowadzi was do edytora i do możliwości wprowadzania tekstu? Nie ważnie gdzie się zakluczycie w pod-pod-pod menu. Kilka ESC i znów możecie wprowadzać kod! Sweet! 🙂

Jeśli nie macie wprawy w pisaniu a chcecie się podszkolić – typing.io jest dla was. Sporo różnych “języków”, sporo lekcji. Każdy znajdzie coś dla siebie aby potrenować.

Macie swój ulubiony i użyteczny skrót w VS?

Przy korzystaniu z nHibernete’a czasem zachodzi potrzeba, aby prócz tabel, które są mapowane z obiektów mieć jakieś dodatkowe. Ja ostatnio miałem taką potrzebę w związku z Quartz.NET, który ma możliwość przechowywania swoich triggerów i akcji w bazie w przypadku, gdy powinny przeżyć restart puli aplikacji.


tl;dr; Potrzebujesz dodatkowych tabel w bazie mapowanej nHibernate’em użyj AbstractAuxiliaryDatabaseObject, ale nie obejdzie się bez haków.

Oczywiście banalnym rozwiązaniem jest stworzenie dodatkowych tabelek ręcznie w bazie i jest to rozwiązanie jeśli musimy mieć je już i na teraz. Jeśli mamy jednak trochę czasu aby zagłębić się w coś ładniejszego i automatycznego to warto to zrobić.

Jak zapewne wiecie (a jak nie wiecie to już wiecie). Do generowania schematu bazy nHibernate ma dostępne klasy SchemaUpdate oraz SchemaExport, które całkiem ładnie sobie radzą z aktualizacją schematu (Update) i generowaniem go na nowo (Export).

Jak więc do tego wcisnąć dodatkowe tabelki? A no istnieje abstrakcyjna klasa AbstractAuxiliaryDatabaseObject, która jak sama nazwa jej wskazuje reprezentuje dodatkowe obiekty w bazie. Obiektem nie musi być tabela co zaraz zobaczymy. Użycie tego wydaje się być proste implementujemy dwie metody:

    public class QuartzTables : AbstractAuxiliaryDatabaseObject
    {
        public override string SqlCreateString(Dialect dialect, IMapping p,
                                               string defaultCatalog, string defaultSchema)
        {
            return File.ReadAllText(Path.Combine(
                                        AppDomain.CurrentDomain.BaseDirectory,
                                        “SqlScripts/create.sql”));
        }
        public override string SqlDropString(Dialect dialect,
                                             string defaultCatalog, string defaultSchema)
        {
            return File.ReadAllText(Path.Combine(
                                        AppDomain.CurrentDomain.BaseDirectory,
                                        “SqlScripts/drop.sql”));
        }
    }

Metody Create i Drop mogą tworzyć dowolny obiekt bazodanowy. Tak jak już wspomniałem wyżej nie muszą to być tylko tabele.
Następnie dodajemy nasz obiekt do konfiguracji:

configuration.AddAuxiliaryDatabaseObject(new QuartzTables());
new SchemaUpdate(configuration).Execute(null, true, false); 

Gotowe? Niestety nie całkiem. Nie wiem czy tylko ja jestem ślepy czy tej informacji nie ma podanej, ale AddAuxiliaryDatabaseObject nie działa z SchemaUpdate. Trzeba posłużyć się SchemaExport. Nie byłoby w tym nic złego, pomijając to, że Export zawsze tworzy tabele od nowa oczywiście gubiąc dane, które były w tych tabelach zapisane. Na mojej maszynie dev nie jest to problem, ale kod wrzucany jest przez TeamCity na środowisko testowe a tam już dane powinny być.

W rezultacie musiałem stworzyć kod, który na podstawie flagi wykonuje albo Update albo Export. Pół-automatyzacja. Nie idealne rozwiązanie, ale na chwilę obecną może być.

Jeśli znacie lepszy sposób na wybrnięcie z tej sytuacji – piszcie. Strasznie denerwuje mnie obecny kod.

Ten wpis o optymistycznym tytule to tylko informacja dla osób, które ostatni miesiąc przespały w jaskini 🙂 Visual Studio 2012 zostało wypuszczone w programistyczną dzicz i od dziś jest dostępne publicznie.


Jeśli ktoś jeszcze nie miał okazji się nim pobawić (osoby mające subskrypcję MSDN mogły zatopić swe zęby już miesiąc temu) powinien spróbować bo, pomijając kilka rewolucyjnych (i dyskusyjnych) zmian, uważam, że ta wersja będzie miała dobre opinie podobnie do wersji 2008. Jest zdecydowanie lepsza od swojej poprzedniczki 2010, którą wiele osób krytykowało za powolność i zasobożerność. W porównaniu z nią VS 2012 to demon :). I choć brzmi to jak tania propaganda MS, to piszę to szczerze :). Więcej informacji na stronie wydarzenia.

Dla zainteresowanych tematem kilka filmów omawiających najnowsze elementy w Visual Studio:

Więcej na stronie serii na channel9. (Nie)stety skupiają się one na wersji Premium oraz Ultimate.

Trochę więcej o nowościach w podstawowej wersji VS 2012 będzie można przeczytać w moim artykule, który pojawi się w najnowszym wydaniu magazyny ‘Programista‘. Zapraszam.

Dziś jest ten dzień. Dziś, każdy .NETowiec, javowiec, python’owiec, javascript’owiec, php’owiec a nawet programista Ady – świętują. Dziś jest 256. (100h, 10000000b, 0400) dzień roku a zatem święto wszystkich programistów. Wszystkiego najlepszego! Mniej bugów i oby kodowanie nadal sprawiało nam przyjemność.

Aby jednak ten post nie był po prostu zwykłym postem z życzeniami dla nas wszystkich postanowiłem coś do niego dodać.


Dziś jest symboliczny dzień dla każdego programisty i sądzę, że tę symbolikę powinniśmy wykorzystać. Zgłaszam wniosek o uczynienie dnia programisty oficjalnym świętem i aby fakt ten uczcić przyznawaniem nagrody dla osoby, która w minionym roku uczyniła najwięcej dla społeczności programistycznej. O wyborze osoby/osób powinna decydować kapituła złożona ze znanych osób i oczywiście powinna obejmować większość języków programowania. Jako, że jednak chciałbym zapoczątkować tę nową tradycję, a mój światek kończy się na .NET (no może nie kończy, ale dość znacznie jest do tej technologii zawężony) to moim zdaniem w tym roku nagroda powinna pójść do…. (werble)….

Rafała i Michała za DevDay 2012

Dawać nagrodę za imprezę, która się jeszcze nie odbyła? I Tak, choć jeszcze kilkadziesiąt dni do niej , że będzie zajebiście. Procent pisał już o zajebistości tego wydarzenia. Patrząc na listę prelegentów zastanawiam się czy to na pewno jest impreza w Polsce i nie mogę uwierzyć, że gratis jest. Panowie – kudos! Kudos za sprowadzenie takich prelegentów i kudos za budowanie wydarzenia, o którym będzie można rozmawiać poza Polską (o tym niech świadczy fakt, że impreza została wymieniona w The Morning Brew). Kudos za alternatywę dla MTSa i w ogóle za imprezę na której będzie można się spotkać i pogadać z braćmi i siostrami programistami. Trzymam kciuki za tę i za kolejne edycje.

I mam nadzieję, że tyle wazeliny wystarczy, aby na DevDay’a się dostać 🙂

Często słyszy się, że programiści powinni pisać kod, który nie będzie silnie zależeć od pozostałych elementów. Dobrze jakby był oparty na interfejsach, a klasy oraz metody nie były zbyt duże aby dało się go łatwo ogarnąć i zrozumieć. W ogóle – ma być cud-miód.
Pytanie tylko jak tego dokonać nie zaprzęgając zbyt wielkich zasobów ludzkich do sprawdzania tego wszystkiego “ręcznie”? Z pomocą tu przychodzi NDepend – narzędzie do statycznej analizy kodu. Zobaczmy, jak więc może ono nas wspomóc w codziennej, ciężkiej pracy programisty.


Instalacja narzędzie jest bajecznie prosta bo jej nie ma (najprostsze rozwiązania są najlepsze :]) – wystarczy tylko rozpakować i już możemy działać.

Strona główna narzędzia

Strona główna

Strona główna przypomina trochę tę znaną z VS. Daje nam dostęp do najbardziej potrzebnych funkcji i sugeruje, co możemy zrobić.
Mamy więc listę ostatnio badanych projektów, możemy także rozpocząć analizę solucji bądź też pojedynczych projektów. Ciekawa jest też opcja porównania 2 wersji tego samego kodu. Więcej o tym później.
Jako dodatek mamy też możliwość zainstalowania NDepend’a jako dodatku do VS oraz do Reflectora. Tego ostatniego nie używam (przerzuciłem się na inne rozwiązania) a dodanie NDpened’a jako AddIn’a do Visual Studio da nam dostęp do wszystkich funkcji narzędzia bez wychodzenia z naszego ulubionego edytora. Help zawarty w sekcji ‘Getting Started’ pozwoli nam zapoznać się z możliwościami i rozpocząć pracę z narzędziem pełną parą. Tyle jeśli chodzi o ekran startowy. Zobaczmy, co mamy dalej.

Po wybraniu ‘VS solutions and VS projects’ NDepend jest na tyle miłe, że listuje nam projekty, nad którymi ostatnio pracowaliśmy, więc nie musimy ich szukać. Nice. Dodatkowo daje nam możliwość filtrowania po tym, w której wersji VS był tworzony projekt – od 2005 (ktoś jeszcze pamięta?) do najnowszego 2012. Sweet 🙂

Jako, że ostatnio pracuję nad kodem dotnetomaniaka (wprowadzając to mniejsze to większe zmiany) postanowiłem zbadać kod KiGG’a, na którym jest on oparty.
Po analizie projektu otwiera się strona raportu. Strona, bo NDepend zwraca nam raport z analizy w postaci strony HTML.

Strona raportu

Raport od razu podaje nam najbardziej kluczowe informacje. Metryki aplikacji – liczbę linii kodu, assemblies, przestrzeni nazw itp.
Raportuje także o regułach, które nasz kod łamie i które powinniśmy w jakiś sposób usunąć.
Fajnie, że przy każdej złamanej regule widzimy zapytanie (o nich będzie później), którego wykonanie poskutkowało wypluciem tych a nie innych obiektów niespełniających norm.

Lista problematycznych klas

Kilka dużych klas, którym dobrze by było się przyjrzeć. Podobnie w przypadku pozostałych reguł, którym NDepend poddaje nasz kod. Nawet nie wiem ile ich jest, ale przeglądając grupy reguł jest tego sporo. Jeśli jednak czegoś by nam brakowało, spokojnie możemy sobie to dopisać, bo NDepend dostarcza język CQLinq, podobny do LINQ język zapytań do tworzenia reguł. Niektóre reguły są (dla mnie) dziwne – np. poprzedzanie pól statycznych przedrostkiem s_ a po komentarzu w regule (// This naming convention provokes debate. Don’t hesitate to customize the regex of NameLike to your preference.) widać, że nie tylko dla mnie. Na szczęście można je dla danego projektu wyłączyć, zmienić czy też usunąć.
Reguły są dość ciekawie pomyślane, np. jeśli w twojej wersja UI NDepend wykryje odwołania do kodu z nhibernate’a zaraportuje ci, że tak być raczej nie powinno i fragment ten powinno się zmienić. Dzięki temu uczy dobrych praktyk pisania. Inne reguły trzeba troszkę tuningować np. reguła ‘Declare types in namespaces’ jest przydatna, ale trzeba ją zmodyfikować o warunek, aby nie brała pod uwagę typów anonimowych, bo inaczej trochę opcji zaraportuje. Szybka edycja reguły i odpisanie warunku && n.ChildTypes.Any(x=>x.IsGeneratedByCompiler == false) załatwia sprawę.

Czego mi brakowało tutaj (albo ja tego nie znalazłem) to możliwość odpalenia danej reguły z poziomu edytora Queries and Rules Edit. Mój flow pracy był taki, że poprawiłem kod, który daną regułę łamał i chciałem zobaczyć, jaki wpływ mają moje zmiany na nią. Zamiast uruchomić tylko tę jedną trzeba było odpalić cały zestaw. Reguły działają szybko, więc nie był to problem jednakże przydałaby się opcja uruchamiająca tylko jedną. Na szczęście skrót ALT-F5 ratuje po części sytuację i umożliwia uruchomienie sprawdzania reguł.

Jak już napatrzymy się na złamane reguły – możemy zerknąć na bardziej obrazową formę mówiącą, co nieco o naszym kodzie a mianowicie diagramy.
Do wyboru mamy kilka: graf zależności, macierz zależności, metryka wielkości oraz abstrakcja vs. instancyjność (?).

Dwa pierwsze to po prostu różne sposób na zobrazowanie co od czego zależy w naszym kodzie. Graf albo macierz do wyboru, do koloru. Co kto lubi 🙂

W KiGGu, jak widać, jest całkiem pokaźne drzewo zależności.

CQLinq

CQLinq ma swój własny edytor, który może nie działa jakoś wyjątkowo szybko (pracując z nim widać zauważalne opóźnienia), ale spełnia swoją funkcję a dodatkowo daje nam podpowiedzi, co do pisanej reguły, więc nie trzeba ciągle sięgać do dokumentacji. Zapytania mogę bazować na kilku dostępnych kolekcjach danych (tzw. Domenach), które są wystawione przez NDependa. Dla przykładu, jeśli chcemy operować na typach w naszych assemblies wystarczy, że użyjemy JustMyCode, jeśli potrzebujemy dostać się do dll’ek, od których zależy nasz projekt wybieramy – ThirdParty. Jest jeszcze kilka innych, tak więc nie powinno być problemu ze stworzeniem odpowiedniego zapytania. Dodatkowo, jeśli zależy nam, aby dana reguła nie była łamana, możemy oznaczyć ją jako krytyczną. Przy wykryciu złamania takiej reguły NDepend (a dokładniej apka konsolowa) zakończy pracę ze statusem -1, który to zostanie wychwycony przez nasz system CI i odpowiedni raport zostanie wysłany do odpowiednich osób (tę część z wysyłaniem maili musimy zakodować sobie sami – nDepend jest świetny, ale tego nie robi :]).

Okno edytora reguł

Analiza różnicowa

Ciekawą opcją jest możliwość analizy różnicowej. NDepend daje nam możliwość ustalenia wersji bazowej a następnie wyświetlania tylko zmian, które nastąpiły od tejże ustalonej wersji. Dzięki temu NDepend może posłużyć nam za narzędzie trzymające informacje o zmianach w naszym kodzie. Opcja jest o tyle ciekawa, że możemy wyszukać nie tylko zmieniony kod, ale np. tylko kod, który został dodany. Mało imponujące? Co powiecie na możliwość wykrycia zmienionych komentarzy? Czy kodu, który stał się bezużyteczny po zmianach w innych obszarach?
Oczywiście nie namawiam do rezygnacji z repozytorium. git czy svn zawsze się przyda, ale jest to miły dodatek, bo w przypadku wykrycia jakichś zmian możemy je zanalizować bez potrzeby opuszczania IDE.

Build Task

Gdyby za każdym razem po zmianie naszego kodu trzeba było uruchamiać narzędzie i analizować zmiany, to choć NDepend wspiera taki case wyśmienicie za pomocą wspomnianej wyżej analiza, jest lepsza metoda. Można uruchomić NDepend’a jako taska już po buildzie i zintegrować wyniki z wynikami innych testów, które robimy na naszym kodzie po checkin’ie. Szczególnie prosta jest integracja ze świetnym TeamCity, którego używam w swoich projektach. Opisywać całego procesu nie muszę bo jest on podany na stronach NDepend’a – Build Process / Continous Integration / Reporting. 10 minut później mam już wyniki z analizy na zakładce w TeamCity – jedyny minus, że z jakiegoś powodu nDepend potrzebuje ścieżek absolutnych do plików projektu. Oczywiście na sztywno zapisywać ich w pliku msbuilda nie ma sensu, ale i na to jest sposób.

Power Tools

Power Tools to taka mała przydatna aplikacyjna o możliwościach zestawu wytrychów :). Jak brakuje ci czegoś w GUI możesz sobie dopisać i sprawdzić w tej konsolowej aplikacji. Dla przykładu jest tam opcja ‘.NET Framework v3.5 and v4.X installed, Core Public API Changes’, które po chwili działania podaje nam jak na dłoni zmiany w publicznym API pomiędzy tymi dwoma wersjami .NETa. Dzięki niemu dowiemy się, że 18 publicznych typów dostępnych w 3.5 zostało usuniętych w 4.0.

Narzędzie robi ciężką robotę a więc i nie jest bez błędów. Udało mi się je wysypać 🙂

Jakbym miał porównać to Power Tools to taki R2D2. Mały, ale jak czegoś potrzeba to on na pewno to ma lub wie jak to wykonać 🙂 Bardzo fajne narzędzie dla geeka.

By ~DaSK~

Jak na chwilę obecną oceniam nDependa jako przyjaciela w codziennej pracy programisty. Można dzięki niemu wykryć miejsce, którym warto się przyjrzeć, aby kod był lepszy. Sądzę, że posty o nim jeszcze się pojawią, jako że możliwości narzędzia są ogromne.