streda 21. júla 2010

SEO Audit

Dnes spúšťam môj nový projekt SEO Audit na http://seo-audit.sk

nedeľa 21. februára 2010

Book review - Microsoft .NET: Architecting Applications for the Enterprise

MS Press - Microsoft .NET: Architecting Applications for the EnterpriseI've just ended reading of Microsoft .NET: Architecting Applications for the Enterprise (PRO-Developer) from MS Press. It's very valued book for .NET developers and architects.

In the first part book describes fundamental design princiles for design of object oriented software:

  • separation of concerns
  • open/closed principle
  • Liskov's substitution principle
  • dependency inversion principle

In the second part the book describes how to apply design patterns to architect layers of enterprise systems:

  • business layer
  • service layer
  • data access layer
  • presentation layer

As for design patterns this book widely refers on the Patterns of Enterprise Application Architecture from Martin Fowler. In the business layer chapter I expected some detailed description how to design solutions with Windows Workflow Foundation, but this technology is poorly covered in this book. Except for some point outs I think it is good decision to invest your time to the reading of this book.

štvrtok 4. februára 2010

PowerShell and Team Foundation Server API

Team Foundation Server has a great API and you can use it to extend its capabilities or automatize tasks and so on. This API can be also used from PowerShell, which demonstrates this post. You have to know only how to use .NET from PowerShell. Following code uses TFS API to get count of new lines of code added in specified changeset:



   1:  ################################################################################

   2:  #

   3:  #  Get-AddedLinesCountInChangeset

   4:  #

   5:  ################################################################################

   6:   

   7:  param 

   8:  (

   9:      [string] $tfsUrl      = $(throw "TFS URL is required"),

  10:      [int]    $changeSetId = $(throw "Changeset ID is required")

  11:  )

  12:   

  13:  [void][Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")

  14:  [void][Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.VersionControl.Client")

  15:   

  16:  function LinesCountInFile($item, $version)

  17:  {

  18:      $tempFile = [System.IO.Path]::GetTempFileName()

  19:   

  20:      $itemVersion = $vcs.GetItem($item.ServerItem, $version)

  21:      $itemVersion.DownloadFile($tempFile)

  22:      $linesCount = (Get-Content $tempFile | Measure-Object).Count

  23:      Remove-Item -Force $tempFile

  24:   

  25:      $linesCount

  26:  }

  27:   

  28:  function ProcessChange($change)

  29:  {

  30:      if($change.Item.ItemType -eq "Folder")

  31:      {

  32:          return $False

  33:      }

  34:   

  35:      $extensions = ".cs", ".aspx", ".ascx", ".xml", ".xaml", ".config"

  36:   

  37:      foreach ($extension in $extensions)

  38:      {

  39:          if ($change.Item.ServerItem.EndsWith($extension))

  40:          {

  41:              return $True

  42:          }

  43:      }

  44:   

  45:      return $False

  46:  }

  47:   

  48:  $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($tfsUrl)

  49:  $vcs = $tfs.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])

  50:   

  51:  $thisVersionSpec = New-Object Microsoft.TeamFoundation.VersionControl.Client.ChangesetVersionSpec $changeSetId

  52:  $previousVersionSpec = New-Object Microsoft.TeamFoundation.VersionControl.Client.ChangesetVersionSpec ($changeSetId - 1)

  53:   

  54:  $chs = $vcs.GetChangeset($changeSetId)

  55:  $totalLinesCount = 0

  56:  Write-Host

  57:   

  58:  foreach ($change in $chs.Changes)

  59:  {

  60:      if (ProcessChange($change))

  61:      {

  62:          $nameParts = $change.Item.ServerItem.Split("/")

  63:          $fileName = $nameParts[$nameParts.Length - 1]

  64:   

  65:          $thisLength = LinesCountInFile $change.Item $thisVersionSpec

  66:   

  67:          if ($change.ChangeType.ToString().Contains("Add"))

  68:          {

  69:              $previousLength = 0

  70:          }

  71:          else

  72:          {

  73:              $previousLength = LinesCountInFile $change.Item $previousVersionSpec

  74:          }

  75:   

  76:          $added = $thisLength - $previousLength

  77:   

  78:          Write-Host "$fileName             $added" -Fore Yellow

  79:          if ($added -gt 0) { $totalLinesCount = $totalLinesCount + $added }

  80:      }   

  81:  }

  82:   

  83:  Write-Host "------------------------------------------------------"

  84:  Write-Host "Total Lines:            $totalLinesCount" -Fore Green

  85:  Write-Host


If you use TFS 2005/2008 then specify only server url, when TFS 2010 then specify url including the collection.


PowerShell console
Manning - Team Foundation Server 2008 in ActionWrox - Professional Visual Studio 2005 Team System

streda 7. októbra 2009

PowerShell and SharePoint API

PowerShell and SharePoint API is really powerfull combination which can help us to automatize administration and development tasks. SharePoint exposes .NET API which can be typically called from some .NET programming language such as C#. Using this approach we have to write code, compile it and than run. SharePoint API can be also used from PowerShell, this approach removes the step of compilation. Only write a script and run it.

Following PowerShell script demonstrates using of SharePoint API from PowerShell. Script is intended to collectively set the force checkout property of document libraries (Shared Documents) in all webs of the site collection on true.


   1:  #################################################################################

   2:  #

   3:  #  Set-RequireCheckOut

   4:  #  Sets ForceCheckout on document libraries Shared Documents on site collection

   5:  #

   6:  #################################################################################

   7:   

   8:  param

   9:  (

  10:      [string] $siteUrl

  11:  )

  12:   

  13:  [void][Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

  14:   

  15:  $site = New-Object Microsoft.SharePoint.SPSite $siteUrl

  16:   

  17:  foreach ($web in $site.AllWebs)

  18:  {

  19:      foreach ($list in $web.Lists)

  20:      {

  21:          if ($list.Title -eq "Shared Documents")

  22:          {

  23:              $list.ForceCheckout = $True

  24:              $list.Update()

  25:          } 

  26:      }

  27:  }

Manning - Windows PowerShell In ActionMS Press - Inside Microsoft Windows SharePoint Services Version 3

pondelok 21. septembra 2009

Visual Studio Macros

I think Visual Studio macros is interesting feature which is not often used. Using macros you can automate repetitive tasks and increase your development productivity. You can create your own macros using Macro Exlorer (View - Other Windows - Macro Explorer).

My sample shows macro for generating new GUID in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format, which is common task at SharePoint development when writing some stuff in CAML:


   1:  Imports System

   2:  Imports EnvDTE

   3:  Imports EnvDTE80

   4:  Imports EnvDTE90

   5:   

   6:  Public Module SharePointMacros

   7:      Sub CreateNewGuid()

   8:          Dim doc As Document = DTE.ActiveDocument

   9:          Dim textDoc As TextDocument = CType(doc.Object("TextDocument"), TextDocument)

  10:   

  11:          textDoc.StartPoint.CreateEditPoint()

  12:          textDoc.Selection.Insert("{" + Guid.NewGuid.ToString() + "}")

  13:      End Sub

  14:  End Module


To associate your macro with keyboard shortcut go to Tools - Options - Environment - Keyboard, find macro in command list, press shortcut (CTRL+N, CTRL+G) and assign it.


Setting VS keyboard shortcut

When you press the shortcut in code editor, macro will be run and new GUID will be inserted on the cursor position.


APress - Writting Add-Ins for Visual Stutio .NETWiley - Developing Visual Studio .NET Macros and Add-Ins

nedeľa 18. januára 2009

Porovnanie ASP.NET WebForms a ASP.NET MVC

Už dlhšie ako rok je v ASP.NET komunite témou číslo jedna pripravovaný framework ASP.NET MVC.
Moje porovnanie nepopisuje rozdiely na implementačnej ale na vyššej úrovni, na úrovni architektúry. Vzor Model View Controller (MVC) nie je v skutočnosti ničím novým. Prvý krát bol popísaný v roku 1979 a v Java komunite je velmi populárny už mnoho rokov. Len pre zaujímavosť, Microsoft v roku 2003 vnímal vzor MVC trochu inak a jeho implementáciu v ASP.NET si predstavoval takto.

Pre komplexné pochopenie rozdielov medzi ASP.NET WebForms a ASP.NET MVC je podľa môjho názoru potrebné pozrieť sa na vec z rôznych pohľadov:

Typ architektúry

  • pull-based architecture (ASP.NET WebForms) - požiadavka prichádza na view, ten inicializuje natiahnutie (pull) dát

  • push-based architecture (ASP.NET MVC) - požiadavka príde na controller, ten inicializuje natiahnutie dát, vyberie view a dáta "natlačí" (push) do view


Typ webového frameworku

  • komponentové frameworky (ASP.NET WebForms, JSF) - treba v nich riešiť 2 problémy:
    - kam serializovať viewstate
    - výpočtová náročnosť vytvorenia komponentového stromu
    Komponentové frameworky sú vhodnejšie pre intranetové aplikácie využívajúce databázu, pretože poskytujú vyššiu úroveň abstrakcie nad protokolom HTTP.
  • požiadavkami riadené frameworky (ASP.NET MVC, Struts, Spring MVC) - sú vhodnejšie tam, kde je potrebné mať úplnu kontrolu nad výstupom


Komponentové frameworky sú o poschodie vyššie ako požiadavkami riadené z pohľadu abstrakcie ktorú ponúkaju, samozrejme niečo to stojí. V extrémnom prípade sa pri použití komponentového frameworku nemusíme starať o to, že existuje nejaký protokol HTTP alebo jazyk HTML. Dobrá úvaha o webových frameworkoch je tu.

O ASP.NET MVC si treba uvedomiť:

  • je to alternatíva a nie náhrada za WebForms

  • poskytuje viac kontroly nad <html/>

  • je to jednoducho testovateľný framework (testovanie WebForms bolo veľmi komplikované – HttpContext mocking)

  • je jednoducho rozšíteľný framework

  • nie je pre každného (WebForm-oriented mindset is unuseable)


Čo sa zmenilo v porovnaní s ASP.NET WebForms:

  • žiaden ViewState

  • žiaden Postback

  • nevyužívame page lifecycle

  • nevyužívame Controls (veci odvodené od System.Web.UI.Control až na zopár výnimiek)

  • SEO friendly URL

  • <form runat="server"> ... </form> nie je nutný atribút runat


Na záver otázka: Kam zaradiť ASP.NET MVC vzhľadom na úroveň abstrakcie nad protokolom HTTP a jazykom HTML?

ASP < ASP.NET MVC < ASP.NET WebForms

utorok 6. januára 2009

Zlo pri vývoji softvéru

Pred niekoľkými rokmi som definoval základné chyby, ktoré sa neustále opakujú pri vývoji softvéru. Tieto chyby sú aj pri malých projektoch, ktoré vyvíjajú jednotlivci a takisto sa vyskytujú aj v projektoch pre top klientov, ktoré implementujú vývojarské týmy. Ignorácia týchto nedostatkov má za následok, že vyvíjaný systém sa časom stáva neudržiavateľným, resp. jeho údržba a rozširovanie je veľmi časovo a teda aj finančne náročné. Tak tu sú:


1. duplicity - kód obsahuje tú istú funkčnosť naprogramovanú na viacerých miestach. Často to vzniká keď programátori použivajú CTRL+C, CTRL+V. Proti duplicitám sa dá efektívne bojovať priebežným refaktorovaním a využívaním návrhových vzorov. Žial moje skúsenosti sú také, že iba málo programátorov vie efektívne využívať refaktorovacie techniky. Obhájenie refaktorovania pred projektovými manažmentom je však náročné, pretože refaktorovaním sa do systému žiadna funkcionalita nepridáva.


2. mixovanie vrstiev - systém nie je rozčlenený do logických vrstiev. Niekedy aj zdanlivo je, ale pri pohľade na implementáciu teda kód som videl niečo ako pridávanie HTML značiek <b> .... </b> k dátam načítavaným z databázy, resp. SQL prikázy vo webových skriptoch (.aspx, .jsp). Jednoducho ľudia si neuvedomujú čo kam patrí.


3. nesprávne závislosti medzi komponentami - nie je venovaná dostatočná pozornosť manažmentu závislostí medzi komponentami. K takému stavu sa dostaneme lahko ak nemáme jasne definované zodpovednosti každej komponenty.

štvrtok 3. júla 2008

Moq

Moq je zaujímavá knižnica na vytváranie mock-ov, ktoré často používame pri testovaní, konkrétne pri vytvaraní nepravých (mock) implementácií. Páči sa mi jednoduchosť použitia a taktiež to, že využíva nové vlastnosti .NET 3.5 a jazyka C# 3.0 (lambda expressions, ....). V príklade je ukázené vytvorenie jednoduchej testovacej implementácie rozhrania. Kĺúčovým krokom je vytvorenie očakávaní volaní (expectations) jednotlivých členov tvoriacich rozhranie. Týmto krokom špecifikujeme ako bude vytváraný mock reagovať na volanie jednotlivých členov tvoriacich rozhranie (v tomto príklade sú to metódy). Potom získame referenciu na vytvorený mock ku ktorému pristupujeme cez rozhranie a môžeme sa hrať.


   1:  using System;

   2:  using System.Linq;

   3:  using Moq;

   4:   

   5:  namespace NMarian.MoqDemo

   6:  {

   7:      public interface IWeatherService

   8:      {

   9:          string GetCurrent();

  10:          string GetForecast();

  11:      }

  12:   

  13:      class Program

  14:      {

  15:          static void Main(string[] args)

  16:          {

  17:              var mock = new Mock<IWeatherService>();

  18:              mock.Expect(w => w.GetCurrent()).Returns("Sunny day");

  19:              mock.Expect(w => w.GetForecast()).Returns("Summer storm at evening");

  20:   

  21:              IWeatherService ws = mock.Object;

  22:   

  23:              Console.WriteLine("Current weather: {0}", ws.GetCurrent());

  24:              Console.WriteLine("Weather forecast: {0}", ws.GetForecast());

  25:          }

  26:      }

  27:  }

utorok 27. mája 2008

Office Open XML - export do Excelu 2007

Práve som riešil problém exportu dát do formátu OOXML pre Excel 2007. Export do tohto formátu prakticky znamená iba vytvoriť sadu XML dokumentov a tie skomprimovať do ZIP archívu. Keďže sa mi nechcelo študovať špecifikáciu OOXML, rozhodol som sa hladať nejakú knižnicu, ktorá by mi poskytla požadovanú úroveň abstrakcie. ExcelPackage je presne tým čo som hladal.

piatok 11. apríla 2008

LINQPad

Táto zaujímava utilita pripomínajúca Microsoft SQL Server Management Studio slúži na písanie LINQ príkazov (LINQ to SQL). LINQPad je veľmi nápomocný pri učení technológie LINQ to SQL. Zobrazuje výsledky vykonaného príkazu vo forme tabuliek, lambda výraz a taktiež aj SQL výraz.