Zestaw nugetów, które poznałem w ostatnim roku

Według mojej subiektywnej oceny „przydania się ostatnio”:

  1. MadiatR – implementacja mediatora (dla Command & Query)
  2. TypeLITE – generuje C#->TypeScript, opisane przeze mnie TypeLITE: generator C# => TypeScript
  3. Squirrel.WindowsSquirrel: It’s like ClickOnce but Works™, zaoszczędziło nam duuuuużo czasu.
  4. Microsoft.AspNet.SignalR.Client – SignalR znam już dawno i dobrze, po prostu dowiedziałem się że jest też klient w C# i można komunikację Client<->Server oprzeć też na SignalR (czy się powinno to inna kwestia).
  5. StyleCopAnalyzersStyleCopa (wcześniej FxCopa) lubiłem zawsze, jednak ta bilbioteka jest oparta na Roslynie i jest przez to super prosta w użyciu. Mój plik configurujący https://github.com/kmorcinek/dotnet-tools-settings/blob/master/StyleCopDefault.ruleset
  6. JetBrains.Annotations – już to chyba było w projektach w których brałem udział, ale teraz sam zrobiłem setup i użyłem. Skorzystałem z Hunt your bugs in design time
  7. SolutionScripts – dzięki temu z konsoli nugeta w VS mogę korzystać ze skrótów do długich komend (jak np update-database z EF z opcjami który projekt i gdzie szukać konfiguracji).
  8. MoreLINQ – rozszerzenia do LINQ. Jedyna metoda, z której korzystamy, to „DistinctBy” – ale już dlatego warto. Inne się kiedyś pozna.
Opublikowano Programowanie | Otagowano , | Dodaj komentarz

TypeLITE: generator C# => TypeScript

W projekcie Webowym z bogatą logiką FrontEndową zawsze w pewnym momencie stajemy przed problemem synchronizacji klas, które mamy w C# z tymi po stronie FE. Jednym z ułatwień jest korzystanie z TypeScript, który udostępnia silne typowanie po stronie FE. Ciągle jednak może być tak, że klasa w C# rozjedzie się z klasą w TypeScript (np. po refaktoringu).

TypeLITE

TypeLITE is an utility, that generates TypeScript definitions from .NET classes. It supports all major features of the current TypeScript specification, including modules and inheritance.

TypeLITE generuje C# => TypeScript. Oczywiście tylko definicje właściwości/pól, ick implementacja nie miałaby sensu.

C#:

public class Person {
    public string Name { get; set; }
    public List<address> Addresses { get; set; }
}
  
public class Employee : Person {
    public decimal Salary { get; set; }
}
  
public class Address {
    public string Street { get; set; }
}

TypeScript:

interface Person {
    Name: string;
    Addresses: Address[];
}
  
interface Employee extends Person {
    Salary: number;
}
  
interface Address {
    Street: string;
}

Przykład użycia

Poniżej opiszę przykład z mojego aktualnego projektu. W trakcie implementacji pojawiło się kilka problemów.

  • TypeLITE uruchamia się w momencie wykonywania „Run custom tool” (albo zapisujemy) na pliku TypeLite.Net4.tt i generuje klasy do plików TypeLite.Net4.d.ts oraz Enums.ts. Takie ustawienie było domyślnie i tak zostało. Przy takim ustawieniu czasami można zapomnieć wygenerować wszystko TypeLITEm i poprawić definicje w FE. Wyjdzie w trakcie CodeReview lub w Runtime
  • Jest kilka sposobów na wskazanie klas z C#, które mają być wygenerowane. Te fajne (otagowanie atrybutem) jakoś nie zadziałały. Więc w pliku konfiguracji TypeLite.Net4.tt zdefiniowałem je explicite:
    //...	
    <# var ts = TypeScript.Definitions()
    		.For<KMorcinek.Examples.UserDto>()
    		.For<KMorcinek.Examples.Features.ListAdultUsersQuery>()
    //...	
    

    Nie musiałem wskazywać każdej klasy, wystarczy że podałem te „ostateczne”. Gdy UserDto posiada AddressDto to AddressDto również zostanie wygenerowane.

  • Następnie explicite podałem, z które projekty należy przeszukiwać. Początek pliku w moim przypadku wyglądał tak:
    <#@ template debug="false" hostspecific="True" language="C#" #>
    <#@ assembly name="$(TargetDir)TypeLite.dll" #>
    <#@ assembly name="$(TargetDir)TypeLite.Net4.dll" #>
    <#@ assembly name="$(TargetDir)$(TargetFileName)" #> // means current WebApp project
    <#@ assembly name="$(TargetDir)YourProject.Domain.dll" #>
    <#@ assembly name="$(TargetDir)YourProject.Application.dll" #>
    
  • skorzystałem z customizacji, która sprawiała że nazwy w TS są camelCase
    <# var ts = TypeScript.Definitions()
    //...
        .WithMemberFormatter(identifier => 
            Char.ToLower(identifier.Name[0]) + identifier.Name.Substring(1)
        );
    

    podejście dosyć proste (zmienia tylko pierwszą literę), ale działa. Jeśli chcesz aby „VAT” zostało zmienione na „VAT” zamiast „vAT” to trzeba chyba podpiąć kod podobny do JsonNetSerializera.

  • kolejna customizacja polegała na podmianie namespace na coś krótszego.
    <# var ts = TypeScript.Definitions()
    //...	
        .WithModuleNameFormatter(module => { 
            return module.Name == "System" ? "System" : "YouApplicationName"; 
        })
    

    Dla Guid’ów (w namespace System) był System, dla pozostałych „YouApplicationName”. Nie chcę się bawić ze zbyt długimi namespace’ami.

  • Konfiguracja generowania podczas procesu buildowania – nie powiodła się, chociaż poszło na to kilka godzin. Należało doinstalować dodatkowy pakiet do VS, ale było to zbyt kruche rozwiązane i nie miałem czasu, żeby to rozkminić. Na razie zostawiłem jak jest, poczekam na lepsze czasy.

Problem zapętlenia budowania C# i TypeScript’a

Narzędzie TypeLITE potrzebuje do prawidłowego działania zbudowanych dll’ek projektów, z których pobiera klasy/modele.

Problem #1:

  1. Załóżmy, że zmieniamy coś w definicji klasy, np. dodaliśmy nową

    właściwość

  2. Wykonujemy „Run custom tool” (albo zapisujemy) na TypeLite.Net4.tt
  3. Ale … coś poszło źle, generator miał błędy i wygenerowany plik TypeLite.Net4.d.ts jest pusty
  4. W związku z powyższym nie możemy przebudować całej solucji ponieważ TypeScript rzuca błędami. Z tego miejsca już nie da się ładnie wrócić

Rozwiązanie:

  1. git checkout -- *.Net4.d.ts wracamy do poprzedniej wersji wygenerowanego pliku, teraz FE się builduje prawidłowo
  2. Poprawiamy w C# to co było źle
  3. Przebudowujemy wszystko
  4. Wykonujemy „Run custom tool” (albo zapisujemy) TypeLite.Net4.tt, co powoduje wygenerowanie poprawnego pliku TypeLite.Net4.d.ts

Problem #2:

W przypadku dodania nowej klasy do C# i dodania do niej ścieżki w pliku TypeLite.Net4.tt, i nie przebudowanu całej solucji przed regenerowaniem aktualnego TypeScriptu znowu może pojawić się się problem z brakiem definicji w plikach TypeLite.Net4.d.ts oraz Enums.ts.

Rozwiązanie:

Rozwiązanie dokładnie takie samo jak opisane w Problemie #1.

Inne

Jak tak o tym piszę to widzę że „Net4.” jest zbyt często powtarzane i prawdopodobnie mogę to usunąć.

Miejsce na improvement:
będę wdzięczny gdyby ktoś fajnie opisał jak debugować to coś 🙂

Opublikowano Programowanie | Otagowano , , | 1 komentarz

Nazywanie commitów

Ostatnio miałem małe Pair Programming poza pracą (tak można się w ten sposób uczyć!).

Padł zarzut że nie powinno się nazywać commitów w stylu “Create PatientService class” tylko jaka jest funkcjonalność dodana. Zgodzę się z tym. Z tym, że aby tak było to trzeba najpierw mieć napisaną całą funkcjonalność krok po krok, przejść process CodeReview (za pomocą Pull Request), następnie wyczyścić commity (git rebase interactive) i wtedy wychodzi nam jeden (kilka?) commitów mających domenowy sens. I tak staram się robić.

Niestety rzeczywistość obok mnie jest mniej różowa, czasem poprawka goni poprawkę. Wtedy siłą rzeczy commit wyglądają jak “Fix: change number variable to long”, “Add missing PatientService class”, “Filter itemsRepository by PartId”. Naprawdę niewiele zmienia gdy na początku commita doklei się ticket z JIRY czy inne TFS. W historii jest po prostu sieczka.

Przy okazji, a może przede wszystkim: How to Write a Git Commit Message

Opublikowano git | Otagowano , , , , | Dodaj komentarz

Literówki w kodzie, komentarzu i na głównej

Mam już taki wzrok, że widzę literówki i nie przepuszczam im. Po prostu taki już jestem, tak mój mózg pracuje. Oczywiście nie toczę wojen w zespołach o to. Są już automatyczne narzędzia które to wychwytują (dodatek ReSpeller do ReSharpera), a resztę sobie poprawię sam, to sama przyjemność.

Można więc myśleć, że to aż tak się nie zwraca bo w sumie kod się uruchomi niezależnie od tego czy klasa się będzie nazywać ArticleTpeConwerter czy ArticleTypeConverter. I że ten porządek, pomoże generalnie projektowi, ale przejdzie to na pewno niezauważone.

Ale, ale

Właśnie zdałem sobie sprawę, że te wszystkie niechluje, które się niczym nie przejmują (i walą literówki i nawet nie chce im się poprawiać po sobie) robią to samo z tekstami, które idą do klienta.

Inspiracja (można przeczekać minutę o CV, później jest o pracy):

Opublikowano Programowanie | Otagowano | 2 komentarze

Reguła DRY – tip #1

DRY – Don’t Repeat Yourself. Łamanie tej reguły ma tyle twarzy, że postanowiłem każdy mały przykład wrzucać.

Gorszy kod:

string GetFilePath()
{
    return IsForDebug
        ? $@"{Folder}\{Name}.{Extension}.{VersionNumber}"
        : $@"{Folder}\{Name}.{Extension}";
}

Lepszy kod:

string GetFilePathBetter()
{
    var filePath = $@"{Folder}\{Name}.{Extension}";

    if (IsForDebug)
    {
        filePath += $".{VersionNumber}";
    }

    return filePath;
}

Wiem że nie powinno się sklejać ścieżki w ten sposób tylko użyć Path.Combine(). Przykład z kodu.

Po komentarzu @marfusios2 zdałem sobie sprawę, że można to ulepszyć do

string GetFilePathMaybeBetter()
{
    var postfix = IsForDebug
        ? $".{VersionNumber}"
        : "";

    return $@"{Folder}\{Name}.{Extension}{postfix}";
}

Ciągle jest jeden zbędny string, ale już zdecydowanie krótszy.

Opublikowano Programowanie | Otagowano , | 3 komentarze

Moje lokalne standardy pracy z gitem

Dorobiłem się już kilku wypracowanych przez lata małych standardów przydatnych w pracy z gitem. Stosowane LOKALNIE, mają więc sens tylko w mojej lokalnej pracy i muszą być wyczyszczone przed wykonaniem PUSHA.

  • Rozpoczynanie od „−− ” – jest to commit, który jest tylko lokalny i powienien być na pewno w całości usunięty przez pushowaniem. Może to być lokalna podmiana bazy danych, jakaś zmiana ułatwiająca szukanie aktualnego buga.
  • „.” (kropka) – oznacza na tyle małą rzecz, że po prostu kropka
  • „…” – powinno być dołączone do poprzedniego commita (f – fixup gdy robimy interactive rebase). Niby można od razu zrobić git commit --amend, ale jednak jest częścią czegoś większego, gdzie chcę jeszcze przez jakiś czas mieć osobne commity.
  • „…prev” – trochę jak poprzednio tylko powinien byc doklejony do jednego z poprzednich commitów.
  • „wip” – skrót od „Work In Progress”, coś na szybko, bo nie miałem czasu wpisać właściwego opisu, trzeba było szybko sprawdzić coś na innym branchu etc.
  • „wip treść commita” – gdy jesteś w trakcie czegoś to lepiej to zaznaczyć na początku commita niż na końcu (wtedy wyglądało by „treść commita wip”)
  • „++ treść commita” – gdy jesteś w trakcie czegoś czegoś większego, a zmiana którą zrobiłeś (nie jest cześcią aktualnego feature’a) powinna pójść prosto na branch develop
Opublikowano git | Otagowano , | Dodaj komentarz

MasterCoder – CODING KOKS FIREFOX

mastercoder

W dzisiejszej odsłonie reflektory sławy padają na konkurs MasterCoder. Wreszcie było mi dane sprawdzić się w rozwiązywaniu zadań algorytmicznych na czas. Każdego dnia zmagałem się z nowymi zadaniami programistycznymi (weekendy na szczęście były wolne na regenerację umysłu). O 20 wpadało nowe zadanie i zaczynała się jazda, kto pierwszy ten lepszy, ale przede wszystkim liczyła się jakość. Zazwyczaj wysyłałem odpowiedź o 22. Następnie czekanie do 8 kiedy to spływały wyniki i ewentualnie można było wysyłać ponowne rozwiązania zadań.

Właśnie ok tej 21:30 spadały na mnie najtrudniejsze decyzje. Czy już wysyłać? Czy może jeszcze dopieścić? Moje testy przechodzą, ale czy pokryłem wszystkie przypadki? Czy dobrze zrozumiałem opisany problem? Adrenalina, presja czasu, zmęczenie… Wykonujący się kod jest bezlitosny. Jakże odmienne warunki od tego co ma się na co dzień w pracy. Wszyscy wiedzą jaka jest proza życia.

morcinek-ranking-mastercoder-2016

Ranking finałowy i zaznaczony ja. No cóż, postarałem się, walczyłem jak lew;) i jadę na finał. Odbędzie się w sobotę w Łodzi podczas konferencji Mobilization. Pierwszy etap to „Jeden z dziesięciu”, do kolejnego przechodzą 3 osoby i będzie to już live coding. No cóż, trzymajcie kciuki 😀

DLA PRAWDZIWYCH WYMIATACZY KODU – sprawdź czy podołałbyś zadaniom konkursowym.

Moje rozwiązania zadań umieszczone na GitHubie: https://github.com/kmorcinek/MasterCode2016

Opublikowano Programowanie | Otagowano | 2 komentarze