Latest Event Updates

Droga przejścia na F# z projektu pisanego w C#

Posted on Updated on

Jak należy przepisać istniejący kod (nie wszystko należy przepisać, ale na pewno nowy kod w C# powinien być pisany w oparciu o to) w C#:

– proste struktury danych muszą być immutable
– złożone struktury danych (zawierający kolekcje innych struktur) “powinny” być immutable (nie mam jeszcze na tyle doświadczenia, żeby stwierdzić czy bardziej “muszą” czy “powinny”)
– kod powinien być pisany bez for i foreach a zamiast tego z użyciem LINQ (Select, Zip, SelectMany, Concat, itd…)
– świat bez nulli – wytłumaczę później

Advertisements

Sposób na wyrugowanie nulli z projektu

Posted on Updated on

null to zło: https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare

A teraz jak sobie z tym radzę:
– nigdzie explicite nie tworzyć null
– uczynić wszystkie obiekty immutable z konstruktorem mającym Guardy przeciw null, zapobiegnie to inicjalizowania nullami gdy nic nie zostało ustawione explicite
– uważać na metody LINQ typu FirstOrDefault(), więc albo unikać “OrDefault”, czyli korzystać z First(), Single(), albo odpowiednio zająć się sytuacjami gdy jednak ten defaultowy null może być przekazany
– Guardy na input z zewnętrz do naszych serwisów, chodzi o wywołania naszego kodu przez kod kliencki (ale gdyby to miał być UI to sytuacja jest analogiczna – nie wpuszczać nulli).

Przeoczyłem coś oczywistego?
Czy może ktoś uważa, że to jest naiwnie zbyt proste i się nie uda.

Pomysły na kolejne posty

Posted on Updated on

Taka moja lista TODO:

* Kod before/after gdy unikamy powtarzania kodu wewnatrz if i else. Może obrazek z gitk. no i kod swoją drogą.

* Kod before/after, przekład gdy zamiaste filtrować dane przed wejściem do metody (i mieć customowego Guarda), zrobić to już w środku. Odpada test.

* Testy których nie pisać – powielanie Guardów, czy nulle, czy wartości >=0

* Co to jest Guard.

* Przetłumaczenie https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/

* Filmik o:
* Jak w gicie poprawić instniejący commit: wycofać commita, z poziomu SourceTree wybrać tylko to co istotne i zrobić nowego commita.
* jak zrobić poprawne “git pull –rebase” i jak wygląda gdy ktoś to źle zrobił.

Dan North – Decisions, Decisions

Posted on

Ciekawsze kawałki:

Developer vs Tester perspective on testing


do 15:26

WIP

Biblioteka Refit lepsza od RestSharp

Posted on Updated on

Po lekturze Exploring refit, an automatic type-safe REST library for .NET Standard i zamienieniu bibliotek w jednym projekcie mogę stwierdzić że Refit jest po prostu lepszy.

Tak wygląda korzystanie z niego:

public interface IGitHubApi
{
    [Get("/users/{user}")]
    Task<User> GetUser(string user);
}


var gitHubApi = RestService.For<IGitHubApi>("https://api.github.com");

var octocat = await gitHubApi.GetUser("octocat");

RestSharp problem z deserializacją

Przy okazji jeśli wywala wam się serializacja w RestSharp’ie to może powodem jest brak domyślnego Json.NET – Newtonsoft serializera. Opis jak sobie z tym poradzić

Zapętlone projekty? – rozwiązaniem interfejs

Posted on

Mam projekt Persistence, który odpowiada za połączenie interfejsów repozytoriów z EntityFrameworkiem (Architektura heksagonalna). Dużą częścią tego projektu są SampleData. Są to dane, którymi seedujemy baze za starcie, aby można było wyklikać skomplikowane scenariusze na podczas Demo, oraz aby na nich można było odpalać UI testy w Selenium. (aplikacja pobiera dane z innych źródeł więc niemożliwe jest wypełnienie danych poprzez wyklikanie z przeglądarki).

Tak wyglądał kod, gdy wszystko było w jednym projekcie:

class MyContext : DbContext
{
    public DbSet<User> Users { get; set; }
}

class MigrationsConfiguration : DbMigrationsConfiguration<MyContext>
{
    protected override void Seed(MyContext context)
    {
        SeedConfiguration.Seed(context);
    }
}

class SeedConfiguration
{
    public static void Seed(MyContext context)
    {
        var user = new User
        {
            Id = 1,
            UserName = "John Galt"
        };

        context.Users.AddOrUpdate(x => x.Id, user);
    }
}

Ten SampleData był już osobnym katalogiem i zaczał z czasem bardzo rosnąć. Stało się jasne, że Persistence sam w sobie bardzo rzadko się zmienia (czasem jakieś migracje, nowe pola), czyli jest “stabilny”. Natomiast SampleData było żywe (nowe rzeczy, refactoringi itp).

Jest to więc znakomity kandydat do wydzielenia nowego projetku. I tutaj pojawił się problem. Persistence potrzebowało mieć referencję do SampleData, aby wywołać explicite metodę Seed(), a SampleData potrzebowało referencję do Persistence aby mieć DbContext na którym operuje.

Tego problemu nie zauważyłem od razu, dopiero na końcu wydzielania nowego projektu uderzyło mnie to. Cięzko było to obejść :/ Próbowałem coś w stylu ładowanie dynamiczne dll’ek z katalogu i skanowanie refleksja kto implementuję metodę którą chcemy wywołać – wszystko HACKy. Nie warto robić hacków więc zostawiłem temat. Po miesiącu rozwiązanie samo mnie uderzyło gdy wcale o nim nie myślałem 🙂 i był to nowy interfejs.

Kod gdy mamy dwa projekty i Persistence ma referencję do SampleData

// SampleData project
public interface ISampleDataContext
{
    DbSet<User> Users { get; set; }
}

class SeedConfiguration
{
    public static void Seed(ISampleDataContext context)
    {
        var user = new User
        {
            Id = 1,
            UserName = "John Galt"
        };

        context.Users.AddOrUpdate(x => x.Id, user);
    }
}

// Persistence project
class MyContext : DbContext, ISampleDataContext
{
    public DbSet<User> Users { get; set; }
}

class MigrationsConfiguration : DbMigrationsConfiguration<MyContext>
{
    protected override void Seed(MyContext context)
    {
        // works cause MyContext implements ISampleDataContext
        SeedConfiguration.Seed(context);
    }
}

Czyli eleganckie rozwiązanie zgodne z OOP.

Od siebie mogę dodać, że nawet jeśli wydzieleniu tego projetku było ważną rzecza (nie tylko ja widziałem tą potrzebę) to nie warto było robić z tego powodu dirty HACKA. Czasem lepiej poczekać, pogadać z różnymi ludżmi… Czasem ktoś nam poda dobre rozwiązanie a czasem ono samo do nas przyjdzie.

Niepisane (już spisane) zasady w projekcie C#

Posted on Updated on

Chciałem po prostu spisać dla potomnych rzeczy które dotychczas może nie były spisane.
Będą dopisywane nowe.

  • nazywanie zmiennej “_” oznacza, że ta zmienna jest nieistotna i pomijamy ją w dalszym kodzie, mimo że musimy jej użyć. Najczęściej pojawia się w lambdach, ale jest też kilka przykładów w pozostałym kodzie, np:

    static readonly ConcurrentDictionary<string, UserModel> LoggedInUsers;
    
    public static void Unsubscribe()
    {
        UserModel _;
        LoggedInUsers.TryRemove(Login, out _);
    }
    

* Przeczytana i zrozumiana książka Clean Code, Czysty kod
* R# nie sugeruje zamieniania na var.
* nie używamy ref i out.
* brak zakomentowanego kodu, jeśli coś kiedyś byśmy potrzebowal, to do tego służy system kontroli wersji (git)
* korzystanie z tooli (R#, StyleCop etc), jeśli jakaś reguła może być automatyczna to ludzie nie powinni tracić czasu na ręczne (mentalne) Code Review.