Warsztaty z Angulara

W poprzednim tygodniu miałem przyjemność poprowadzić warsztaty dla studentów Politechniki Łódzkiej na temat SPA, Angulara i ogólnie JS.

Moje warsztaty były częścią eventu ‚CaseWeek’ organizowanego przez IAESTE. Frekwencja studentów dopisała, feedback również był pozytywny, także jestem zadowolony :)

Materiały dostępne na github

Unikaj magicznych stringów

No chyba, że to część bielizny. Naprawdę, co jakiś czas znajduję w różnych kodach takie kwiatki (na szczęście w moich coraz rzadziej 😉 ), gdzie ręce opadają, a i głowa boli od debugowania.

Magiczne stringi, czyli coś co wpisujemy w kod na sztywno, w możliwie wielu dziwnych miejscach, wmawiając sobie, że to tak na chwilę, albo to nie może nic popsuć. Może :)

[csharp]
bool condition = field.AwesomeStringFlag == "ture";
if(condition )
{
//…. : (
}
[/csharp]

No i nie działa, jak to możliwe? Przecież flaga jest, zgadza się, wartość true jest ok… :)

[csharp]
bool condition = field.AwesomeStringFlag == true.ToString().ToLower();
if(condition)
{
//…. : )))
}
[/csharp]

Ten i mu podobne przykłady literówek można mnożyć, w końcu zawsze klawisz może się omsknąć i już zamiast value mamu valie. Osobną kategorią są błędy w angielskich nazwach zmiennych/propertek/metod, to też czasami może przyprawić o zakłopotanie.

Tyle, przed kolejnym wstawianiem magicznego stringa, czegoś co „na pewno się nie zmieni”, gdzie „nie możemy popełnić przecież błędu”, zastanówmy się :)

Czas na prywatę, malowanie obrazów

Odchodząc trochę od tematów programistycznych :) Moja Kochana Narzeczona jest studentką ASP, nieźle, co? Zrobiłem dla Niej małą stronkę (bootstrapik i troszkę phpa :P), gdzie znajduje się oferta dotycząca malowania obrazów na zamówienie.

Strona: Obrazy na zamówienie

Polecam, zlecenie może dotyczyć malowania obrazu ze zdjęcia, fragmentu istniejącego obrazu, kopii jakiegoś dzieła itd.

Łódzkie Dni IT

Jakiś czas temu prowadziłem małą prezentację dla studentów na Uniwersytecie Łódzkim (już 3ci raz, hihi). Wśród wielu corocznych prezentacji, które przeważnie są albo bardzo marketingowe, albo totalnie o niczym, chciałem pokazać coś, co przyda się już na studiach.

Padło na TDD i dwa wzorce projektowe: Strategia i Repozytorium. Z własnego doświadczenia wiem, że dużo łatwiej robiłoby mi się projekty na algorytmy, gdybym pisał je w C# zgodnie z TDD :) Było minęło, ale chociaż tym młodym chciałem dać krótka zajawkę jak to ugryźć 😉

pliczki: https://github.com/WujoWojtas/ldi_2014

Ogólnie uważam, że mogłem tę prezentację zrobić dużo lepiej, chyba mimo wszystko za dużo chciałem pokazać, może następnym razem :)

Metoda rozszerzająca nie boi się nulla

Metody rozszerzające pojawiły się w C# 3.0. Od tamtej pory towarzyszą nam na każdym kroku, sam kiedyś nie zdawałem sobie sprawy z ich używania 😉

Metoda rozszerzająca, czyli taka, która rozszerza, powiększa zestaw metod jakimi dysponuje jakaś klasa/struktura, nawet w dawno skompilowanej DLLce. Ogólnie ten temat poruszany był w internetach wielokrotnie, ja chciałem jednak zaznaczyć bardzo ciekawą właściwość metod rozszerzających, o której często się zapomina.

Metoda rozszerzająca nie boi się nulla!

Jak to?

Wywołanie metody rozszerzającej wygląda w kodzie dokładnie tak samo jak wywołanie metody „normalnej”, czyli np

[csharp]
string x = "alaMaKota";
x.ToString(); //metoda "normalna";
x.ExtensionMethod(); //metoda rozszerzająca, o ile taką mamy gdzieś zadeklarowaną
[/csharp]

dobra, przypuśćmy, że mamy taki kodzik:

[csharp]
static class ExtensionMethods
{
public static int GetLengthExt(this string value)
{
if (!string.IsNullOrWhiteSpace(value))
{
return value.Length;
}
return -1;
}
}

//wywołanie
var strArray = new[] { "10", null, "alaMaKota" };
foreach (var str in strArray)
{
Console.WriteLine(str.GetLengthExt());
}
//output
/*
2
-1
9
*/
[/csharp]

i o dziwo, przy drugim obiegu pętli foreach nie dostaniemy NullReferenceException, co wydarzyłoby się gdyby nie była to metoda rozszerzająca. Gdzie więc ta magia?

Kolejny przykład i pod nim wyjaśnienie:

[csharp]
using System;

namespace TestExt
{
class Program
{
static void Main(string[] args)
{
string x = null;
Console.WriteLine(x.GetLengthExt());
Console.WriteLine(GetLengthStatic(x));
}

static int GetLengthStatic(string str)
{
if (!string.IsNullOrWhiteSpace(str))
{
return str.Length;
}
return -1;
}
}

static class ExtMethods
{
public static int GetLengthExt(this string str)
{
if (!string.IsNullOrWhiteSpace(str))
{
return str.Length;
}
return -1;
}
}
}
[/csharp]

otóż nie ma praktycznie żadnej różnicy w IL dla wywołania:

[csharp]
//x.GetLengthExt();
IL_0004: call int32 TestExt.ExtMethods::GetLengthExt(string)
IL_0009: call void [mscorlib]System.Console::WriteLine(int32)

//StaticGetLength(x);
IL_0010: call int32 TestExt.Program::GetLengthStatic(string)
IL_0015: call void [mscorlib]System.Console::WriteLine(int32)
[/csharp]

także wywołanie metody rozszerzającej jest zamieniane na wywołanie „zwykłej metody statycznej” :) Stąd też „odporność” na nulle. Ładnie.

Oczywiście odporność na nulle jest też oczywiście uzależniona od implementacji, jednakże jeżeli wewnątrz metody nie zapomnimy sprawdzić czy obiekt wywołujący nie jest nullem, nic złego się nie stanie.

Taka to była ciekawostka.

linq.js – zaznać troszkę C# w javascript

Postawiłem przed sobą dość proste zadanie dodania nowego ‚ficzeru’ do pewnej wewnętrznej ministronki w firmie. Ot, taka mała lista obsługiwanych aplikacji. Z biegiem czasu ‚mutacji’ produktu powstało wiele, dlatego lista stała się dość pokaźna i znalezienie czegoś w niej stało się trudne.

Szczerze mówiąc nie szukałem gotowych rozwiązań problemu, czyli dynamicznej wyszukiwarki (wpisujemy np „Apli” i mamy wyświetlone linki zawierające w anchorze część „Apli”), na pewno bym coś takiego znalazł, jednak czasami fajnie jest napisać coś samemu.

Doszedłem do momentu, w którym pomyślałem „kurde, gdyby w js było linq…” – jest. linq.js to darmowa biblioteczka, która daje nam praktycznie wszystko co najlepsze ze znanego nam dobrze LINQ w .net :)

Powiedzmy, że mamy taki oto html:
[html]
<input type="text" id="search" />
<ul id="list">
<li><a href="#">A</a></li>
<li><a href="#">AB</a></li>
<li><a href="#">ABC</a></li>
<li><a href="#">ABC</a></li>
<li><a href="#">D</a></li>
</ul>
[/html]

teraz chcemy uzyskać listę linków, które w anchorze będą zawierać tekst wpisany w #search

[js]
var text = $(‚#search’).val().toLowerCase();
var links = $(‚#list li a’);
var result = Enumerable.From(links )
.Where(function (x) { return $(x).text().toLowerCase().indexOf(text)>-1; })
.OrderBy(function (x) { return $(x).text() })
.ToArray();
[/js]

jak widać, możemy korzystać z metod znanych nam z .net + korzystać także z innych bibliotek js, takich jak popularne jQuery 😉

Działający przykład zamieszczam na jsfiddle: http://jsfiddle.net/HGey5/1/ (nie znam na tyle js, ale jeżeli nie robię $(result).clone(), to przy $(‚div’).append(e) kasuje mi elementy z wejściowej listy ul… Nie wiem dlaczego. Z clone() działa 😉 )

Adobe Muse, proste stronki w 5 minut?

Miałem ostatnio, w prawdzie bardzo krótką, styczność z programem Adobe Muse. Co to takiego? Jest to część Adobe Creative Cloud, służy do tworzenia bogatych w efekty wizualne stron internetowych.

Cały soft jest jeszcze dość młody, pierwsza stabilna wersja wyszła w 2012 roku, jednak wydaje się być dobrze dopracowany. Korzystając z niego miałem wrażenie że częściowo wróciłem do czasów FrontPage, jednakże nie jest to negatywne odczucie, po prostu taka nostalgia 😉

Od razu powiem, że korzystałem z niego przez jakieś 2h, a moim celem było przygotowanie w pewnym niecnym celu prostej stronki, dlatego żadnych tricków i myków tutaj nie zamieszczę. Muse wspiera tworzenie mocno hierarchicznych witryn. Na etapie projektowania dodajemy nowe podstrony, gdzie mamy możliwość ustawiania ich względem siebie (równorzędne, podrzędne). Możemy i powinniśmy zdefiniować także „Wzór”, czyli swego rodzaju layout/MasterPage, żeby nie kopiować na każdą stronę np loga, czy kolorystyki.

Adobe Muse posiada wbudowanych kilka przydatnych ‚widżetów’, jak np prosty formularz kontaktowy czy menu, z którego to dziś skorzystałem 😉 Fajną rzeczą było to, że menu od razu wie jakie podstrony i w jakiej konfiguracji mamy dodane, także wypełnia się samo. Mamy możliwość customizowania wyglądu, także całkiem spoco.

Program na pewno będzie przydatny dla osób nie mających pojęcia o html/css (swoją drogą nie widziałem opcji by samemu kod modyfikować…), można w naprawdę krótkim czasie uzyskać fajny efekt. Osobiście na ten moment zakończyłem swoją przygodę z tym programem, jednak zawsze warto mieć świadomość jakie alternatywy i gotowe rozwiązania już istnieją :)

ASP.net MVC: DisplayTemplate, EditorTemplate

ASP.net MVC to fajny framework :) Przy okazji przygotowań do egzaminu 70-486 zdałem sobie sprawę, że nie wiedziałem do tej pory o tak przydatnej rzeczy jak własne DisplayTemplates i EditorTemplates. Troszkę wstyd, jednak człowiek podobno uczy się całe życie 😉

Z czym to się je?

[csharp]
@Html.EditorFor(m => m.UserName)
[/csharp]

Wszyscy znamy helpery wbudowane w ASP.net MVC, które pozwalają nam w łatwy sposób tworzyć „kontrolki” htmlowe, jak textBoxy, checkBoxy itd. Praktycznie zawsze łączymy je z danymi z modelu, by potem wykorzystać w akcjach kontrolera, nie zastanawiając się jak to naprawdę działa. Otóż dla standardowych typów takich są gotowe specjalne templatki, odpowiednio do wyświetlania i wprowadzania/edytowania danych. Sam framework w wielu miejscach pozwala nam na rozszerzanie swoich możliwości, nie inaczej jest w tym miejscu, a pole do popisu jest spore (helpery edycji i wyświetlania rozbudowanych modeli)

Jak stworzyć własne „kontrolki”?

Musimy przygotować specjalne widoki (osobno dla Display, osobno dla EditorTemplate). Tak, tylko widoki. Jedyne zastrzeżenie, to że muszą być one odpowiednio nazwane i być umieszczone w dedykowanym folderze dla widoków kontrolera w którego widokach mają mieć zastosowanie (albo w folderze ogólnym Views/Shared) oraz w odpowiednim folderze dla swojego zastosowania (np Views/Home/DisplayTemplates albo Views/Shared/EditorTemplates).

I tak, np dla stworzenia naszej pierwszej templatki do wprowadzania i wyświetlania danych typu Int32 musimy stworzyć widoki Int32.cstml w folderach DisplayTemplates i EditorTemplates.

DisplayTemplate, Views/Shared/DisplayTemplates/Int32.cshtml
[csharp]
@model Int32?

Wybrano wartość: @Model
[/csharp]

EditorTemplate, Views/Shared/EditorTemplates/Int32.cshtml
[csharp]
@model Int32?

@{
var data = Enumerable.Range(0, 10);
}

Wybierz liczbę: @Html.DropDownList("", new SelectList(data, Model))
[/csharp]

Wywołanie
[csharp]
@{
int test = 7;
}
@Html.EditorFor(m => test)
@Html.DisplayFor(m => test)
[/csharp]

Efekt w html
[html]
<select id="test" name="test" data-val-required="Pole Int32 jest wymagane." data-val-number="The field Int32 must be a number." data-val="true">

<option selected="selected">
7
</option>

</select>
Wybrano wartość: 7
[/html]

Jeżeli w naszym „helperze” nie podamy name dla danej kontrolki html, domyślnie dopasuje się do tego dobra nazwa, czyli nazwa propertki/zmiennej z modelu. Dla mnie bardzo spoco.

Oczywiście to tylko banalny przykład, jednakże jeżeli jeszcze ktoś o tym nie wiedział, tak jak ja do tej pory, a siedzi już trochę w ASP.net MVC, to od razu wyczuje jakie to daje możliwości 😉

W przypadku złożonych modeli, oczywiście w templatkach do nich możemy używać innych templatek, np właśnie dla pól typu Int32 czy Boolean.

Użyteczne atrybuty z System.Runtime.CompilerServices.

.Net Framework w wersji 4.5 oferuje nam dość przydatną przestrzeń nazw, System.Runtime.CompilerServices. Mnogość klas, atrybutów może przytłoczyć, ja z tego miejsca chciałem pokazać moim zdaniem najprzydatniejszy atrybut, oraz dwójkę jego mniej przydatnych braci.

CallerMemberName, to atrybut, który potrafi rozpoznać, kto go wywoływał. Tzn jaka metoda czy propertka obiektu wywołującego została użyta w danym momencie.

Zastosowanie? Najszybciej do głowy przychodzi WPF i konieczność implementowania interfejsu INotifyPropertyChanged, gdzie w „klasycznej” wersji podawaliśmy ręcznie nazwę propertki, której wartość była aktualizowana.

1. Wersja „prosta do bólu”

[csharp]
private int number;
public int Number
{
get { return number; }
set
{
number = value;
OnPropertyChanged("Number");
}
}

void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
[/csharp]

2. Zastosowanie CallerMemberName

[csharp]
private int number;
public int Number
{
get { return number; }
set
{
number = value;
OnPropertyChanged();
}
}

void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
[/csharp]

Znacznie ładniej? Tak, należy zauważyć, że zmienna oznaczona atrybutem CallerMemberName musi mieć swoją wartość domyślną, inaczej kompilator wyrzuci nam błąd.

3. Inne przykłady

[csharp]
static void Test()
{
Test2();
}

static void Test2([CallerMemberName] string name = null, [CallerFilePath] string path = null, [CallerLineNumber] int lineNumber = 0)
{
Console.WriteLine(name);
Console.WriteLine(path);
Console.WriteLine(lineNumber);
}

static void Main(string[] args)
{
Test();
}
[/csharp]

tutaj zostały przemycone dwa pozostałe ciekawe atrybuty: CallerFilePath oraz CallerLineNumber. Zastosowanie? Mi jako pierwsze do głowy przychodzi logowanie błędów :)

Podsumowując, atrybut CallerMemberName jest ciekawą nowością w .Net 4.5, który może znacznie ułatwić i uodpornić na proste błędy aplikacje korzystające z INotifyPropertyChanged.