sobota 13. prosince 2014

Poznámky z code review 1

Občas dělám i code review hotového kódu a některé věci se neustále opakují či se vyskytují v kódu poměrně často a tak mne napadlo, že by nebylo špatné na ně upozornit a nabídnout k zamyšlení či diskuzi. První příspěvek bude věnován kódu, který provádí rozhodnutí dle výčtové hodnoty, tedy enumu.

Například vznikne takovýto výčtový typ:

public enum Option
{
    One = 1,
    Two = 2
}

Výše uvedené hodnoty pak často vedou k programátora k rozhodování se pomocí následujícího kódu, kdy předpokládá, že buď má proměnná jednu určitou hodnotu a pokud ne, tak musí mít druhou.

if (userOption == Option.One)
    Console.WriteLine("One");
else
    Console.WriteLine("Two");

Což ovšem platí jen do okamžiku, než někdo přidá další hodnoty, například doplní definici enum takto:

public enum Option
{
    Unknown = 0,
    One = 1,
    Two = 2,
    Three = 3
}

Podobné chyby se ale my programátoři často dopouštíme, i pokud má výčtový typ více hodnot než dvě a my se z nějakého důvodu domníváme, že stejně může nabývat jen dvou námi vybraných hodnot. Takto napsaný kód není příliš odolný proti změnám ve výčtovém typu a ve výsledku se pak program často chová "podivně".

Jak to tedy napsat správně? Podle mne takto:

switch (userOption)
{
    case Option.One: Console.WriteLine("One"); break;
    case Option.Two: Console.WriteLine("Two"); break;
    default: throw new NotImplementedException();
}

Pokud se objeví hodnota, s kterou kód nepočítal, vyhodí se výjimka. A nebo se může provést úprava hodnoty  a zalogování chyby, aby šlo později daný kód upravit, tedy například napsat kód takto:

switch (userOption)
{
    case Option.One: Console.WriteLine("One"); break;
    case Option.Two: Console.WriteLine("Two"); break;

    default: 
        Console.WriteLine("Not implemented value {0}, processing as {1}"
                             userOption, 
                             Option.One); 
        goto case Option.One;
}

Upozornění: kód je napsán jen pro účely tohoto článku, má jen ilustrovat problém. K podobným chybám může dojít i při nepoužití výčtu, jen se to na něm dobře ilustruje.

středa 10. prosince 2014

Feraty u jezera Garda 3 - Cima Rocca

Výprava na horu Rocca byla  krásným celodenním výletem - v této oblasti jsou hned čtyři feraty:
  • F.Susati,
  • M.Foletti
  • Sent.dei Camminamenti
  • Sent.delle Lasta

úterý 9. prosince 2014

Feraty u jezera Garda 2 - jezero Idro a Sasse

Další ferátkou byla cesta kolem horského jezera Idro. Má jméno Sasse a více informací lze zde. To je necelou hodinku jízdy od severního konce Gardského jezera  a leží i výše - a je tam tedy i o poznání chladněji. A zatímco u Gardy to koncem října ještě žije, tady sezona už skončila. Velké parkoviště bylo zcela  prázdné a na celé feratě jsme potkali jen čtyři další lidi. A panovalo zde ticho.

neděle 7. prosince 2014

Vybaveni na cesty autem - chlazení

Převoz potravin autem a v chladu byla vždy výzva. Na kratší vzdálenosti stačí polystyrénová krabice, zmražené potraviny a chladící vložky - tenhle systém používáme už roky a je to spolehlivý způsob přepravy většího množství potravin na kratší vzdálenosti. Ale pokud se jede někam na více dnů a není možné využívat lednice, nelze se spolehnout na  box, respektive ten není moc použitelný.

pátek 5. prosince 2014

Razor a email

V přechozím příspěvku jsem ukázal, jak využít Razor i mimo web aplikace. Nyní popíši, jak tohoto přístupu využít v případě, že chceme v aplikaci vytvořit email a ten poslat uživateli. Email bude obsahovat i obrázky a přílohu.

Vytvoření šablony pro email

Šablony jsou vlastně dvě. V první je vlastní obsah mailu a tato šablona využívá jinou jako svoji obálku - to je vhodné pro případy, kdy bude potřeba více emailů a všechny by měly mít například jednotný vzhled.


email.cshtml
@* Generator: Template *@

@functions{
    public string Recipient { get; set; }

    public string Sender { get; set; }

    public string Content { get; set; }
}

@{ Layout = new emailLayout();}

<img alt="Logo" src="cid:logo" />

<table width="550" class="headerText">
    <tr><td>Hello Mr.@Recipient</td></tr>
    <tr><td>This is my message for you: @Content</td></tr>
    <tr><td>Regards, @Sender</td></tr>
</table>

emailLayout.cshtml
@* Generator: Template *@

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
    <style type="text/css">
        body {
            font-family: "Lucida Grande","Helvetica Neue",sans-serif;
            font-size: 12px;
            color: #333333;
            background: White;
        }
    </style>
</head>
<body>
    @RenderBody()
</body>
</html>

Vygenerování emailu

Získání HTML mailu je jednoduché - jak ze šablony vyrobit text už bylo ukázáno v předchozím díle, nyní jen použijeme metodu třídy AlternateView k získání HTML obsahu:

Code:
MailMessage mail = new MailMessage();

var htmlContent = (new email { Sender = "Martin", Recipient = "John", Content = "You win!!!" }).TransformText().Trim();
var htmlView = AlternateView.CreateAlternateViewFromString(htmlContent, new ContentType("text/html"));

mail.AlternateViews.Add(htmlView);

Vkládání obrázků

V kódu šablon si můžete všimnout i značek pro zobrazení obrázků. Pokud má email obsahovat obrázky, máte tyto tři možnosti:

  • v tagu img odkázát na existující, veřejně dostupný obrázek na sítí 
  • vložit obrázek do emailu  a odkázat na něj v tagu img pomoci cid:název 
  • vložit obrázek jako base64

Z textu šablon vyplývá, že použiji druhou možnost - jako hodnotu ContentId použijeme hodnotu zadanou za cid: v src atributu příslušeného img tagu:

var attachResource = new LinkedResource(new MemoryStream(<byte[]>));
attachResource.ContentId = <resourceID>;
htmlView.LinkedResources.Add(attachResource);

Vkládání příloh

Pokud chceme k emailu přiložit i přílohu, jde to podobně jednoduše - nejprve si vytvoříme příslušný objekt a pak je přidáme do kolekce příloh mailu:


Attachment att = new Attachment(new MemoryStream(<byte[]>), attachmentName);

mail.Attachments.Add(att); 

Tipy

Pro testování posílání emailů lze použít utilitku Smtp4Dev a    do config souboru aplikace přidáme následující nastavení:

<system.net>
   <mailSettings>
      <smtp from="mail@test.com">
         <network host="localhost" port="25"/>
      </smtp>
   </mailSettings>
</system.net>

Výsledek

Po spuštění pak obdržíme  email, který nás informuje o výhře:



A na závěr snad jen upozornění na možnost podívat a získat celý (zahrnuje i kód z prvního příspěvku na toto téma) funkční kód na Codeplex a jako v předchozím díle je zde i poster (stránka ve formátu A4 v pdf), který stručně shrnuje vše z tohoto příspěvku.

středa 3. prosince 2014

Využití Razor mimo web

Při programování aplikací je často nutné vygenerovat nějaký text - například email - který je částečně pozměněn - například se mění oslovení (pan-paní), jméno (Martin-Petr) apod. Obvyklé postupy jsou buď tvrdě kódové - tedy skládání textu přímo v kódu za využití například StringBuilderu a nebo se použije textový soubor sloužící jako předloha (šablona), kde se vyhledávájí značky a místo nich se vkládá určitá hodnota.
Pokud ale programujete web aplikace v ASP.NET, určitě jste se setkali s MVC a Razorem - a pokud se vám tento přístup líbí - tedy možnost vytvořit si šablonu, do které se v určitých místech vkládají hodnoty a která umožňuje provádět i složitější operace - je možné podobný přístup použít i v non-web aplikacích. Stručně ukáži jak na to.

Co je nutné?

Postupy jsou popsány mnohem stručněji v jiných příspěvcích dostupných na internetu, tak to vezmu stručně:
Nejprve nainstalujte si RazorGenerator za použití následujícícho postupu
  1. Ukončete všechny běžící instance Visual Studia - nechte běžet jen jednu.
  2. Běžte do Tools -> Extension and Updates a vyhledejte Razor Generator
  3. Naistalujte to


Poté pro každý projekt/solution, ve kterém chcete Razor používat, proveďte toto:
  1. Běžte do  Tools –> NuGet Package Manager –> Package Manager Console
  2. Zadejte a spusťte"  “PM>Install-Package RazorGenerator.Templating


A to je vše, nyní již můžete Razor použít ve své aplikaci.

Vytváříme šablonu - příklad


Jak Razor použít popíši na příkladu jednoduché konzolové aplikace:

  1. Do projektu vložte novou položku - greetings.cshtml
  2. Ujistěte se, že tato položka má ve svých vlastnostech jako hodnotu Custom Tool nastaveno RazorGenerator


  3. Zadejte tento kód a ulože změny - na rozdíl od použítí v MVC nemá tato šablona vlastnost Model, ale díky bloku functions můžeme definovat jednotlivé vlastnosti a objekty - nejsme tedy vázání na jeden view model jako v případě MVC:


  4. Vraťte se do Program.cs a do Main metody vložte následující kód:


  5. Spusťte aplikaci a na obrazovce uvidíte:

Nezapomeňte:

Instalace Nuget balíčku začal váš projekt používat knihovnu RazorGenerator.Templating a tak ke scému běhu potřebuje další knihovny, takže nezapomeňte přidat tyo knihovny při šíření své aplikace: 
  • System.Web.Extensions.dll
  • System.Web.Helpers.dll

Zjednodušený přehled výše uvedeného jsem shrnul na jednu stránku A4, kterou si je možné stáhnout zde.









úterý 18. listopadu 2014

Zábavní parky okolo ČR

Bohužel nám v ČR chybí pořádný zábavní park a tak se musí vždy do zahraničí. Tady je přehledná mapka zábavních parků v Evropě - ty lepší jsou zvýrazněny hvězdičkou.  Snažil jsem se zahrnout všechny parky, které mají něco, co alespoň trochu připomíná horskou dráhu.

Jak je vidět, naprostá většina parků leží v Německu - zejména asi jeden z nejlepších parků v Evropě Europa Park.


Ne všechny parky v přehledu stojí za návštěvu, - například bych varoval před polským parkem Wesole Miasteczko  - je to asi tak nejhorší park, co jsme kdy navštívil, díky neschopnosti obsluhy neskutečné čekací doby i když byl park prázdný. U jiných parků je třeba zvážit i vhodný věk na návštěvu. Rakouský Family Park se hodí spíše pro menší děti, německý Legoland asi nadchne děti do 10ti let a pak už je to horší a tak podobně.