Czyli o tym dlaczego warto mieć znany typ zwracanych danych.

Pracując samemu nad projektem raczej to nie ma zbytnio znaczenia, jeżeli zaś pracujemy w zespole rozproszonym w którym różne osoby są odpowiedzialne za różne rzeczy, anonimowość może kopnąć nas w 4 litery.

Wyobraźmy sobie kod (chyba dość prosto to sobie wyobrazić), który z bazy pobiera jakiś obiekt i zwraca go z mapowanego na anonimowy typ:

_context
    .Table
    .Where(x => x.Id == 10)
    .Select(x => new 
    { 
        x.Name, 
        x.Type 
    });

Proste? Nic w tym złego? Sam z tej konstrukcji bardzo często korzystam, albo dokładnie mówiąc korzystałem, bo zaprzestałem ostatnio.

Okazało się, że u nas to się nie sprawdza, gdyż baza danych może ulegać zmianie a zmiana ta nie jest jakoś propagowana w zespole. Raczej… jest może gdzieś wspomniana, ale nie jest ona, powszechnie znana.

O jakiego typie zmian piszę? Na przykład w tym konkretnym przypadku x.Type został zamieniony z nvarchar na relację odwołującą się do innej encji. Co nie tylko zwracało nie to co było potrzebne, ale także nic nie zwracało bo następował problem z serializacją Self referencing loop detected for property.

Zastanawiałem się jaka by musiała być sytuacja bym to wyłapał. Pod względem exception o tylko i wyłącznie test integracyjny. Test jednostkowy uchroniłby mnie tutaj gdybym miał dane testowe generowane z kodu – problem typów by nastąpił. Tylko, co tutaj testować? Logiki nie ma, dane są zwracane z bazy. A testowanie bazy nie należy! do testowania kodu. Więc pozostaje integracyjny test. Ale to też nie zmienia faktu, że błąd zostanie wyłapany dość późno w procesie. A można by tego uniknąć stosując ViewModele lub inne modele zwracające dane do widoku.

Więc ku przestrodze, zwróćcie uwagę co zwracacie i kiedy. Jeżeli możecie to nadajcie temu typ. Ułatwi wam to życia później. To, że nie chcę lub staram się ograniczyć typy anonimowe wcale nie oznacza, że nie wykorzystuje dynamic, dynamic to co innego, gdyż całe podejście do tworzenia i pisania kodu jest wtedy inne.

1 KOMENTARZ

  1. Pomoże jak korzystasz z jakiegoś DBContext (Ef, NH), ale nie podziała jak masz micro-ORM i widoki w bazie. Wtedy to już tylko testy integracyjne :)

Comments are closed.