czwartek, 10 grudnia 2009

TIP: SQL Management Studio Express Error 29506


Kiedy próba zainstalowania SQL Management Studio Express (thank's God It's freeware) kończy się błędem 29506, to znaczy, że instalujesz leciwe już oprogramowanie na systemie operacyjnym z obsługą UAC, kiedy to producenci tego oprogramowania dopiero snuli plany o UAC...
Więc co by się pozbyć tego breakpointa:

1. Uruchom polecenie CMD jako Administrator.
2. Uruchom instalator z poziomu CMD czyli: C:\SQLManagement.msi (lub coś w ten deseń).

Thanks Google...

środa, 28 października 2009

Pomocne w testowaniu witryn na wielu przeglądarkach


Jedną z trudniejszą z rzeczy z jaką spotyka się każdy web developer jest dostosowanie działania witryny i jej optymalizacja wynikająca ze zróżnicowania dostępnych przeglądarek. Każdy spotka się prędzej czy później z piekłem przeglądarek wynikającym z ich wojny o rynek :-) Aktualny ranking firmy Gemius na temat popularności przeglądarek internetowych w naszym kraju przedstawia się następująco:

  1. Firefox 3.x 48,97%
  2. Internet Explorer 7.x 17,23%
  3. Internet Explorer 6.x 9,34%
  4. Internet Explorer 8.x 7,74%
  5. Opera 9.x 5,49%

Do tego dochodzą różne konfiguracje wymienionych wyżej przeglądarek takie jak ustawienia javascript, flash, różne rozdzielczości ekranu itd.

Oto kilka przydatnych narzędzi w testowaniu witryn na wielu przeglądarkach i ich konfiguracjach, które zarazem nie zamienią naszego komputera w śmietnik.

Browsershots.org Robi zrzuty ekranowe podanego przez nas adresu www. Zalety: prostota, długa lista obsługiwanych przeglądarek Wady: czasami trzeba czekać na wyniki kilkanaście minut, witryna musi być dostępna publicznie, niektóre maszyny testujące potrafią się zawieszać. Dodatkowo w sieci istnieje wiele innych witryn o podobnym działaniu: np. komercyjny i rozbudowany CrossBrowserTesting.com.

Internet Explorer Application Compatibility VPC Image Zestaw obrazów VPC systemu operacyjnego WindowsXp wraz z zainstalowanymi przeglądarkami Internet Explorer w wersji 6, 7, 8 (do wyboru). Zalety: otrzymujemy podręczne środowisko testowe, Wady: trzeba mieć odpowiednie zasoby sprzętowe na uruchomienie kilku maszyn wirtualnych. VPC działają jeszcze do stycznia 2010 r.

Expression Web Super Preview Umożliwia podgląd wyrenderowanej witryny z poziomu programu Microsoft Expression Web. Zalety: zintegrowanie podglądu witryny z procesem tworzenia. Wady: wymagany Expression Web

Firefox IE View Wtyczka do przeglądarki Firefox umożliwiająca przełączanie silnika renderującego z/na Internet Explorer-a. Zalety: szybkość działania.

czwartek, 22 października 2009

PG.NET XXII Spotkanie grupy


Chciałbym Was zaprosić na XXII spotkanie Poznańskiej Grupy .NET, które odbędzie się w czwartek 29 października 2009 w siedzibie firmy Cognifide (Aleja Wielkopolska 4, Poznań). Będę na nim prezentował bardzo przydatne narzędzie jakim jest NDepend. Oprócz mojej prezentacji nie zabraknie nowinek ze świata .NET, które przedstawi Marek Błotny. Na koniec będzie o Silverlight 3, Blend 3, .NET RIA Services o czym opowie nam Marcin Kruszyński.

Szczegółowa agenda:
18:00 - 18:10 Wstęp
18:10 - 18:30 Nowinki ze Świata .NET (Marek Błotny)
18:30 - 19:00 NDepend (Dariusz Tarczyński)
19:00 - 19:15 Przerwa
19:15 - 21:00 Silverlight 3, Blend 3, .NET RIA Services - najciekawsze cechy (Marcin Kruszyński)

Udział w spotkaniu jest bezpłatny, a rejestracja uczestników znajduje się tutaj: Rejestracja.

EDIT @ 2009.10.30
Prezentację oraz materiały do niej można pobrać stąd

wtorek, 6 października 2009

PG.NET XXI Spotkanie grupy


Gościem XXI spotkania (2009-10-08 19:00, Aleja Wielkopolska 4, siedziba firmy Cognifide) Poznańskiej Grupy .NET będzie Bartosz Nyczkowski, który pracuje w Microsoft, w grupie, która jest odpowiedzialna na wydajność serwerowych wersji Microsoft Windows.

Oto zagadnienia, które omówi:
- Jak wygląda cykl życia projektu w przypadku Microsoft Windows?
- W jaki sposób jest testowana wydajność systemu?
- Jak od strony praktycznej wygląda praca nad usprawnieniami?
- Jak wygląda współpraca z klientami?

Rejestracja na spotkanie

piątek, 18 września 2009

Agile Poznań: III Spotkanie

Spotkanie Poznańskiej Grupy Praktyków Agile odbędzie sie w siedzibie Cognifide
(Al.Wielkopolskie 4, Poznań) 6 października o godzinie 18:00.

Wojciech Buras poprowadzi prezentacje "TDD w prawdziwym swiecie",
podczas której omówione zostaną miedzy innymi następujące kwestie:
1. Najczęstsze problemy z przełożeniem designu na kod i testy.
2. Czym jest i czym nie jest TDD?
3. Przykład ewolucji designu z pomocą TDD.
4. Promowanie testowalności.
5. Zastosowanie na linii frontu.

Warto się wybrać!

poniedziałek, 14 września 2009

PG.NET: XX Spotkanie grupy


Zapraszamy na pierwsze po wakacjach spotkanie Poznańskiej Grupy .NET.
20. spotkanie PG.NET odbędzie się w czwartek 24 września (Aleja Wielkopolska 4, siedziba firmy Cognifide) od godz. 18:00. Zapowiada się bardzo, bardzo interesująco!

Agenda:
18:00 - 18:15 - Wstęp i kilka spraw organizacyjnych
18:20 - 18:35 - Nowinki w świecie .NET - Skrót informacji ze swiata technologii .NET przygotowany przez Marka Błotnego (Cognifide)
18:40 - 19:00 - Hudson Continuous Integration Engine - Kilka informacji na temat alternatywnego narzędzia CI przedstawi Michał Korsak (ITSoftware.pl)
19:15 - 20:00 - Instalator WiX - Bartek Szafko (Advisor)

W czasie spotkania wśród uczestników rozlosujemy kilka licencji na oprogramowanie firm JetBrains, Developer Express, Telerik oraz Nevron.

Po spotkaniu, już tradycyjnie zapraszamy na część dyskusyjno-nieformalną :)
[Rejestracja, strona grupy]

poniedziałek, 7 września 2009

NDepend. Wiesz z kim tańczysz?

Po konkretnej nieobecności w trybie online powracam do życia - z kolejnymi wpisami znanej treści, tym razem słów kilka o niezwykle użytecznym narzędziu: NDepend.

Czym jest owy NDepend? To narzędzie dla .NET, którego autorem jest Patrick Smacchia. Służy ono do badania i raportowania złożoności oraz jakości tworzonego kodu. Na chwilę obecną posiada 82 metryki wyświetlające bardzo szczegółowe dane. Dodatkowo generator raportów sprawiają, że nawet “nieprogramista” może ocenić w jakiej kondycji jest dostarczony mu kod – narzędzie wszechstronne oraz wręcz nieograniczone. Możliwość integracji z NAnt-em lub MSBuild-em dostarczają automatów do wykonywania tego wszystkiego o czym troszkę napisze za chwilę.

Zacznijmy od początku. Po uruchomieniu NDependa wskazujemy zestaw bibliotek, które chcemy poddać analizie. Nie mam nic mądrego pod ręką, dlatego posłużę się bibliotekami MbUnit.

1 

Program od razu przystępuję do akcji, a oczom naszym ukazuje się dłuuugi raport.

2

I tak, na pierwszy rzut widzimy:

ilość instrukcji IL, ilość linii, kodu, (uwaga) pokrycie kodu przez komentarze, ilość klas, ilość typów itd. O ile niektóre z tych danych, z praktycznego punktu widzenia, możemy potraktować statystycznie, o tyle już np. zależności między samymi klasami, martwy kod, konwencje nazewnicze mogą być tym, czego właśnie szukamy.

Kto, kogo, gdzie…

Wspomniane zależności między modułami mogą być bardzo skomplikowane, przedzieranie się pomiędzy nimi za pomocą Reflectora często po kilkudziesięciu minutach powoduje odruch wymiotny na widok kolejnego “dziedzica”. Na szczęście NDepend jest w stanie to wszystko ogarnąć i mimo że kod nadal pozostaje zakręcony, to my w tym gąszczu powiązań dość szybko możemy dojść do celu.

4

Refaktoryzacja kodu z tym okienkiem staje się wiele prostsza. Często graf może wydawać się zbyt obszerny:

DiagramBoxAndArrowGraphBig

Na szczęście do dyspozycji mamy dodatkowe dokowalne okienko: Dependency Matrix:

5

Skóra węża?

Kolejnym bardzo interesującym widokiem jest okno Metrics. Przypomina ono nieco skórę węża (tak, widzę tam skórę węża :-) ), a ma za zadanie wykonanie rentgena naszego kodu: każda bryła w ogólności symbolizuje klasę, która to składa się z mniejszych kwadracików – naszych metod. Im metoda ma więcej linii kodu, tym kwadracik jest większy. Sczegółowość możemy zawężać przełącznikiem widniejącym u góry okienka, natomiast zbiorcze informacje widzimy w okienku Info.

6

CQL

To nie wszystko! NDepend posiada wbudowany interpreter języka zwanego CQL (Code Query Language). Dzięki niemu piszemy kwerendy zbliżone do języka SQL, które to pozwalają odpytywać się NDependa o interesujące nas dane o naszym kodzie.

Operator projekcji: SELECT

  • METHODS – odpytania do metod
  • FIELDS – odpytania do pól
  • TYPES – odpytania do typów
  • NAMESPACES – odpytania do  przestrzeni nazw
  • ASSEMBLIES – odpytania operujące na bibliotekach

Operator informujący: WARN

  • WARN IF – jeśli spełniony jest warunek

Aby utworzyć kwerendę należy skorzystać z okna CQL Query Edition, które posiada wbudowane podpowiadanie składni z możliwością wizualnego modyfikowania jej parametrów:

7

Przykłady:

1. Wyświetl metody publiczne, które mają więcej niż 30 linii kodu:

SELECT METHODS WHERE NbLinesOfCode > 30 AND IsPublic

2. Wyświetl 10 najbardziej złożonych metod i uszereguj metody ze względu na ich złożoność:

SELECT TOP 10 METHODS ORDER BY CyclomaticComplexity

3. Moja konwencja nazewnicza zabrania nazywania pól statycznych zaczynających się od przedrostka m_ Ostrzeż mnie jeśli znajdziesz takie wystąpienia:

WARN IF Count > 0 IN SELECT FIELDS WHERE NameLike "^m_" AND IsStatic

Słowo końcowe

NDepend to naprawdę niezły kombajn, kilka godzin może okazać się niewystarczające, aby zgłębić możliwości jakie drzemią w tym narzędziu. Warto go poznać, gdyż może uratować nam skórę podczas następnej refaktoryzacji kodu.


Promuj

sobota, 16 maja 2009

ASP.NET MVC oraz IIS 6

Hostowanie aplikacji utworzonej za pomocą frameworka ASP.NET MVC na serwerze IIS 6 jest niestety bardzo problematyczne. Utworzone w ten sposób aplikacje wyświetlają niemiły (i w tym przypadku niezrozumiały) komunikat: 404 Not Found. Dlaczego tak się dzieje?

Żądania przychodzące do serwera są przetwarzane poprzez odpowiednie filtry ISAPI (pomijam dla uproszczenia inne zachodzace tam procesy), zgodnie z mapowaniem odpowiednich rozszerzeń. I tak na przykład .ASPX trafia do filtra aspnet_isapi.dll. Routing ASP.NET MVC wymaga użycia modułu IHTTPModule i wywołania UrlRoutingModule. Niestety to wymaga przejścia przez wymieniony wcześniej filtr aspnet_isapi.dll - a ten domyślnie nie jest w tym przypadku żądany, a serwer wyświetla nam błąd 404.

Ok, jak wyjść z opresji?

Metoda 1: Prosta

Odrazu ostrzegam: ta metoda nie nadaje się do zastosowania w dużych, obciążonych witrynach. Zaraz okaże się dlaczego.

Rozwiązanie to opiera się o wildcard. Polega to na tym, że wszystkie żądania przychodzące do serwera będą puszczane przez aspnet_isapi.dll. Zaletą jest prostota, wadą: każde żądanie: nawet o obrazek, plik .css, plik multimedialny i każdy inny plik będzie wiązał się przejściem przez handler DefaultHttpHandler/StaticFileHandler. Takie rozwiązanie oznacza brak cachowania żądań oraz kompresji. Marnotrawstwo zasobów serwera, a to dla mocno obciążonych maszyn oznacza problemy.

Ok, ale dla developerskich zastosowań takie rozwiązanie będzie wystarczające, więc zaczynamy konfigurację:

1. Otwieramy przystawkę Internetowe Uslugi Informacyjne i klikamy właściwości naszej aplikacji MVC.

2. Przechodzimy na kartę: Katalog macierzysty oraz klikamy przycisk Konfiguracja

screen_02 2009.05.16 20.02


3. Klikamy przycisk Insert, wpisujemy rozszerzenie: .mvc potem lokalizację: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll oraz odznaczamy opcję Sprawdz, czy plik istnieje.

Metoda 2: Zmiana ścieżki routingu

Metoda ta polega na dodaniu rozszerzenia .aspx po nazwie kontrolera, czyli stworzenia ścieżki routingu w ten deseń: {controller}.aspx/{action}/{id}

Niestety tracimy nasze czyste ścieżki, które zapewniało nam MVC.

 

Metoda 3: URL Rewriting

Ta metoda to nic innego jak zautomatyzowanie metody drugiej (odpada nam zmiana ścieżek). Musimy skonfigurować przepisywanie ścieżek tak, aby moduł dopisał znane ASP.NET rozszerzenie i przepuscił je przez odpowiedni filtr.

niedziela, 22 marca 2009

Walidacja danych w ASP.NET MVC za pomocą xVal

Pierwsza zasada programisty: nigdy nie ufaj danym wejściowym. Sama walidacja tych danych może zostać przeprowadzona na wiele sposobów, przekazując odpowiedzialność od warstwy najwyższej do najniższej. Takie podejście pozwala na eliminowanie zagrożenia w wielu przypadkach jeszcze bez przesłania danych do serwera. (Jeśli ktoś nie lubi czytać przydługich wstępów, może przejść od razu do punktu: "Dlaczego xVal?").


Walidacja po stronie warstwy prezentacji
<asp:TextBox ID="TextBox1" runat="server" />
<asp:RequiredFieldValidator ID="reqVal" runat="server" 
       ErrorMessage="Please enter a value" ControlToValidate="TextBox1" />
<asp:Button ID="Button1" runat="server" Text="Button" />



Należy pamiętać, że walidacja po stronie klienta (JavaScript) ZAWSZE musi iść w parze z walidacją po stronie serwera. W przeciwnym razie, to tak jak by w ogóle tej walidacji nie było! Wywołanie metody PageIsValid:

protected void Button1_Click(object sender, EventArgs e) 
{ 
  if (Page.IsValid) 
  { 
    // TextBox1 posiada wartość.
  } 
}



Walidacja po stronie logiki biznesowej

private static void Validate (EmailAddress myEmailAddress) 
{ 
  if (myEmailAddress.ContactPersonId <= 0) 
  { 
    throw new InvalidOperationException("Błąd, brak odpowiedniego ContactPersonId!"); 
  } 
  if (string.IsNullOrEmpty(myEmailAddress.Email))
  { 
    throw new InvalidOperationException("Błąd, brak emaila!"); 
  } 
  if (!IsValidEmailAddress(myEmailAddress.Email)) 
  { 
    throw new InvalidOperationException("Błąd, wprowadzony email jest błędny!"); 
  } 
} 
public static int Save(EmailAddress myEmailAddress) 
{ 
  Validate (myEmailAddress);
  myEmailAddress.Id = EmailAddressDB.Save(myEmailAddress);
  return myEmailAddress.Id; 
} 



Walidacja po stronie serwera SQL

ALTER TABLE  dbo.Category ADD CONSTRAINT
CK_Category CHECK (SortOrder >= 0  AND SortOrder <= 100)
GO   



Wykorzystanie dostępnego frameworka do walidacji danych, np:


Przedstawione frameworki różnią się przeznaczeniem. Ja przedstawię w tym poście świeży jeszcze projekt xVal.


Dlaczego xVal?


  1. Stworzony do użycia z ASP.NET MVC

  2. Wspiera walidację client-side oraz server-side

  3. Możliwość lokalizacji językowej komunikatów

  4. Oparty o przyjęte "dobre techniki"

  5. Możliwość włączenia do projektu bez konieczności przeprowadzania "wielkich" zmian

  6. Lekki, 1 plik .dll do podłączenia

  7. Open source

  8. Mało znany, bo nowy :-)



image-thumb



Zaczynamy. xVal - validation framework for ASP.NET MVC applications.



Po stronie modelu, xVal opiera swoje działanie o atrybuty. Z tego względu atrybuty naszych klas musimy odpowiednio oznaczyć atrybutami. W moim projekcie posiadam klasę Order.cs, którą będę poddawał torturom walidacji:

public class Order
{
    [Required] [StringLength(15)]
    public string ClientName { get; set; }
 
    [Range(1, 20)]
    public int NumberOfProducts { get; set; }
 
    [Required] [DataType(DataType.Date)]
    public DateTime Date { get; set; }
}



Objaśnienie zastosowanych atrybutów:

  • [Required] : dany atrybut jest wymagany, nie może być pusty.

  • [StringLength(n)] : dany atrybut musi posiadać odpowiednią długość, dla typu String.

  • [Range(n, m)] : dany atrybut musi być z przedziału od, do.

  • [DataType(typ)] : dany atrybut musi być zgodny z podanym typem.




Należy jeszcze dodać referencję do: System.ComponentModel.DataAnnotations.dll

Nadszedł czas na kontroler. Ja wszystkie operacje dotyczące składania zamówień będę przeprowadzał w HomeController.

public class HomeController : Controller
{
    [AcceptVerbs(HttpVerbs.Get)]
    public ViewResult CreateOrder()
    {
        return View();
    }
 
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult CreateOrder(Order order)
    {
        OrderManager.PlaceOrder(order);
        return RedirectToAction("Completed");
    }
 
    public ViewResult Completed()
    {
        return View();
    }
}



Klasa OrderManager:

public static class OrderManager
{
    public static void PlaceOrder(Order order)
    {
        var errors = DataAnnotationsValidationRunner.GetErrors(order);
        if (errors.Any())
            throw new RulesException(errors);
 
        // Business rule: Nie można składać zamówień w niedzielę
        if(order.Date.DayOfWeek == DayOfWeek.Sunday)
            throw new RulesException("ArrivalDate", "Nie można skłdać zamówień na niedzielę!", order);
 
        // Todo: zapis do bazy danych, pliku xml lub cokolwiek innego
    }
}



Czas na widok CreateOrder.aspx

<h1>Zamówienie pluszowego misia</h1>
<% using(Html.BeginForm()) { %>
    <div>
        Nazwa: <%= Html.TextBox("order.ClientName") %>
        <%= Html.ValidationMessage("order.ClientName") %>
    </div>
    <div>
        Ilość misiów: <%= Html.TextBox("order.NumberOfProducts")%>
        <%= Html.ValidationMessage("order.NumberOfProducts")%>
    </div>
    <div>
        Data dostawy: <%= Html.TextBox("order.Date")%>
        <%= Html.ValidationMessage("order.Date")%>
    </div>                
 
    <input type="submit" />
<% } %>



Potrzebujemy jeszcze prostą i niezmienną klasę ValidationRunnera, gdyż  DataAnnotations takiej nie posiada:

internal static class DataAnnotationsValidationRunner
{
    public static IEnumerable<ErrorInfo> GetErrors(object instance)
    {
        return from prop in TypeDescriptor.GetProperties(instance).Cast<PropertyDescriptor>()
               from attribute in prop.Attributes.OfType<ValidationAttribute>()
               where !attribute.IsValid(prop.GetValue(instance))
               select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty), instance);
    }
}



Musimy jeszcze zmodyfikować napisany wcześniej szkielet metody CreateOrder w kontrolerze HomeController, tak aby błędy były przechowywane w stanie modelu.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateOrder(Order order)
{
    try {
        OrderManager.PlaceOrder(order);                
    }
    catch(RulesException ex) {
        ex.AddModelStateErrors(ModelState, "order");
    }
 
    return ModelState.IsValid ? RedirectToAction("Completed")
                              : (ActionResult) View();
}



Tym oto sposobem zakończyliśmy walidację po stronie serwera. Czeka nas jeszcze implementacja sprawdzanie po stronie klienta.

screen_02 2009.03.22 14.18




Walidacja po stronie klienta (Client-side validation).
Wszystko czego będziemy potrzebować do wykonania walidacji za pomocą javascriptu, to biblioteka jquery.validate.js oraz xVal.jquery.validate.js (ten znajduje się w folderze z projektem xVal). Należy je skopiować do folderu z naszymi skryptami (/Scripts) oraz podlinkować je do naszego MasterPage.

<head>
    <script type="text/javascript" src="<%= ResolveUrl("~/Scripts/jquery-1.2.6.js")%>"></script>
    <script type="text/javascript" src="<%= ResolveUrl("~/Scripts/jquery.validate.js")%>"></script>
    <script type="text/javascript" src="<%= ResolveUrl("~/Scripts/xVal.jquery.validate.js")%>"></script>
</head>


Czas teraz na import helperów xVal, najlepiej zrobić to raz w pliku Web.config:

<system.web>
  <pages>
     <namespaces>
        <!-- leave rest as-is -->
        <add namespace="xVal.Html"/>
    </namespaces>
  </pages>
</system.web>



Wracamy do widoku oraz dodajemy linijkę służącą do wymuszenia walidacji po stronie klienta. Będzie ona zastosowana dla kontrolek prefixowanych przez nazwę order:

<%= Html.ClientSideValidation<Order>("order") %>



Od tej pory walidacja po stronie klienta powinna być uruchamiana, "potajemnie" korzystając oczwyiście z atrybutów, które definiowaliśmy wcześniej. Super!


W załączniku przesyłam zlokalizowany przeze nnie na nasz język plik z komunikatami.

poniedziałek, 16 marca 2009

C2C '09 - relacja

Communities 2 Communities 2009 już za nami, chciałbym krótko podsumować całe spotkanie.

Po pierwsze: podziękowania dla Adama Najmanowicza z Cognifide za zasponsorowania busa dla członków PG.NET!

Mój poniższy komentarz dotyczy jedynie ścieżki .NET. Mam nadzieję, że organizatorzy udostępnią jakieś video z SQLa :-)

1. Marek Byszewski, "Tour de VSTS 2010".

Prezentacja była szybkim przeglądem możliwości Visual Studio Team System 2010. Marek dość sprawnie prezentował możliwości debugera historycznego, zarządzania kodem oraz continuos integration za pomocą Visual Studio.  Aplikacja jeszcze nie jest wolna od wad - o czym można było się przekonać na własne oczy. Marek jednak dość sprawnie przechodził pomiędzy nie do końca udanymi próbami, całość wypadła w miarę sprawnie. Na szczęście (moim zdaniem) plan Marka został wykonany prawie do końa, nie licząc paru problemów technicznych o których wspomniałem. Merytorycznie nie zobaczyłem nic wielkiego, czegoś czego do tej pory bym nie znał. Ocena 7,5/10.

2. Julia Lerman, "My favorite Entity Framework. Tips & Tricks".

Julia zaprezentowała wybrane problemy z którymi spotyka się większość progrmistów wykorzystujących EntityFramework oraz przestawiała sposoby ich rozwiązania. Prezentacja była prowadzona po angielsku, nie było jednak żadnych problemów ze zrozumieniem przekazu - Julie z niczym się nie śpieszyła i płynnie przedstawiała kolejne punkty prezentacji. Doskonały kontakt z publiką, dużo energii w przekazywaniu wiedzy, pełen profesjonalizm. Ciekawe przykłady z życia wzięte i brak niezrozumiałej teorii. Ocena 10/10.

3. Piotr Leszczyński, "Kolejny kontener Dependency Injection? NIE - dziękuję! Czyli o koncepcji meta-kontenera słów kilka".

Tak naprawdę zastanawiałem się o czym będzie ta sesja. Koncepcja meta-kontenera nie była mi za bardzo znana, a chciałem się dowiedzieć u źródła "o so chosi". Pomyślałem sobie, że pewnie będzie o IoC - trochę tak było. Szybkie wprowadzenie do tematyki Inversion Of Control, dependency injection, oraz przejście do meritum prezentacji, czyli meta-kontenera. Słuchałem, słuchałem i cały czas zastanawiałem się gdzie jest to odkrycie. Widziałem idee opartą o jeden wielki wzorzec fabryki, ale wydawało mi się, że jest coś jeszcze poza tym. Zadałem Piotrkowi pytanie "Jaki cel przyświecał wymyśleniu meta-kontenera i do czego jest mi on potrzebny, skoro wszystko to, co chcę zrobić z IoC udustępnia mi mój obecny, ulubiony kontener?". Piotrek odpowiedział, że uniezależnie mnie to od zmiany licencji mojego kontenera w przyszłości. Pytanie kolejne: "A co jeśli Wy zmienicie licencję meta-kontenera?". Odpowiedz: <brak>. Odniosłem wrażenie, że prezentacja była pewnym środkiem na przedstawienie produktu, natomiast to co najciekawsze w samym IoC zostało potraktowane po macoszemu. Ocena: 6/10.

4. Ingo Rammer, "Hardcore Production Debugging of .NET Applications".

Ingo dał czadu! Wyśmienita wręcz prezentacja narzędzi służących do debugowania gotowego managed-kodu, była wykonana w sposób jaki najbardziej przypadł mi do gustu. Narzędzia, które przedstawiał Ingo, ani nie posiadały fajowskich wizualnych bajerów, nie miały latającego menu, ani pomocy w postaci spinacza. Mimo to, zostały zaprezentowane w taki sposób, że nie spuszczałem wzroku z ekranu projektora. Absolutnie nie było żadnej rzeczy do której mógłbym się przyczepić. Ocena 11/10.

5. Udi Dahan. "Avoid a Failed SOA - Business and Autonomous Components to the Rescue".

Udi to wielki autorytet w naszym małym świecie :-) Byłem przekonany, że pod względem merytorycznym nie mam się o co martwić i dowiem się rzeczy, o których nawet nie śniłem, na pewno bedzie pro. Było pro. Niestety tematyka sesji była dla mnie nieco "akademicka". Rozumiem, że nie samym pisaniem kodu człowiek żyje, ale nie było nawet jednej linijki kodu :-( Udi potrafił nad jednym slajdem przegadać dobre 10 minut, mimo tego nie "lał wody". Za przydatność informacji dałbym 5/10, za prezentację 10/10. Końcowa ocena: 7/10.

6. Artur Paluszyński, "Interakcyjne sceny 3D w Windows Presentation Foundation".

Artur prezentował techniki 3D za pomocą WPF-a. Prezentacja dość spokojna, mimo to ciekawa. Wszystko o czym mówił Artur uznawałem za godne uwagi. Zwracałem jednak uwagę na formę prezentacji "per Państwo". Artur, jesteśmy na C2C, tu wszyscy jesteśmy kumplami po fachu! Końcowa ocena 9/10.

7. Konferencja C2C 2009. Ocena końcowa.

Szkoda, że nie była bliżej Poznania :-)  - jednak z mojej strony dla organizatorow tego przedsięwzięcia - WIELKIE BRAWA. Kawał dobrej roboty. Zdecydowanie najlepsza tego typu impreza w kraju!

piątek, 13 marca 2009

Po XVII spotkaniu PG.NET. Krótka relacja.

To już po 17 spotkaniu PG.NET, na której to gościliśmy Raymonda Lewallena, importowaną gwiazdę z za oceanu :-)

Zajebiście ciekawa prezentacja o BDD, ale przy okazji  - o mojej preferowanej metodologii - TDD. Występ Raymonda był bardzo udany. W sposób bardzo zrozumiały przedstawił o co tak naprawdę chodzi w BDD. Wiele można poczytać o tym podejściu w internecie, jednak dopiero Raymond troszkę zaraził mnię tym podejściem, wyjaśniając przy tym różne niuanse z tym związane.

Spotkanie "w cztery oczy", po spotkaniu, w restauracji na Starym Rynku również podniosło kilka ważnych spraw, często nie związanych z BDD :-) Osobiście jednak dostało mi się od Raymonda za (do tej pory tak myślałem) "rewolucyjne" podejście do uruchamiania tasków CruiseControl-a i innych NAntów, i MSBuildów z poziomu plików .bat :-( No cóż, może rozwiązanie nie jest idealne, ale pracuję nad wersją 2.0 (powered by PowerShell) :-)

Raymond obiecał wrócić za rok. No to czekamy!

środa, 4 marca 2009

Bardzo ciekawy marzec. Co trzeba zobaczyć?

W marcu uzbierało się wiele ciekawych wydarzeń. Do najciekawszych należy zaliczyć:

 pgnet 11 marca (Poznań). Na 17. spotkaniu poznańskiej grupy .NET będziemy mieli specjalnego gościa – Raymonda Lewallena. Raymond będzie opowiadał o Behavior Driven Development. Raymond Lewallen (C# MVP), prelegent znany z takich konferencji jak TechEd czy VS Live, wysokiej klasy specjalista z 15 letnim doświadczeniem w pisaniu aplikacji dla sektora publicznego i rządu amerykańskiego. [http://bartekszafko.pl]

10927 12-14 marzec (Kraków). W dniach 12-14 marca, w Krakowie, odbędzie się V już edycja Studenckiego Festiwalu Informatycznego - największej tego typu imprezy w Europie Środkowej.
Studencki Festiwal Informatyczny to międzynarodowa konferencja skierowana do pasjonatów informatyki z całej Polski. Impreza tworzona jest "przez studentów dla studentów", dzięki temu, celnie trafia w gusta odbiorców i zapewnia niespotykaną gdzie indziej atmosferę. Podczas Festiwalu poruszane jest szerokie spektrum zagadnień takich jak inżynieria oprogramowania, systemy operacyjne, sieci, czy Open Source. Różnorodność tematów gwarantuje, że każdy uczestnik znajdzie coś dla siebie.

 startup 13 marca (Poznań). Poznańskie Centrum Superkomputerowo-Sieciowe oraz StartUp-IT zapraszają do wzięcia udziału w warsztacie: "Tworzenie serwisów internetowych - część II z II" [http://startup-it.pl/].

 

c2 14 marca (Warszawa). Communities2Communities (C2C) edycja 2009 to konferencja organizowana zjednoczonymi siłami grup technologicznych z całej Polski. C2C to niepowtarzalna okazja, aby spotkać i posłuchać najwyższej klasy specjalistów z Polski i ze świata. Tegoroczna konferencja obejmuje aż trzy ścieżki tematyczne: przeznaczoną dla profesjonalistów IT, SQL Server oraz .NET. Na każdą ze ścieżek przypada pięć sesji - każda z nich będzie prowadzona na najwyższym poziomie, w sposób mertoryczny, przez najlepszych specjalistów, bez zbędnego marketingowego bełkotu. [http://c2c.org.pl]

win 18 marzec (Warszawa). Już 18 marca w Warszawie odbędzie się pierwsze spotkanie z cyklu czterech spotkań technologicznych, podczas których zapoznamy Cię z nową odsłoną systemów Microsoft Windows, rozwiązaniami wirtualizacyjnymi oraz narzędziami umożliwiającymi zarządzanie środowiskiem IT opartym na systemach Microsoft.

cebit 3-8 marzec (Hanower, Niemcy). Z zagranicznych konferecji: jest CEBIT. Na targach pojawi się 20 polskich przedsiębiorstw m. in.: Imagis, AVSystem, BKT Elektronik, Denco Logic, Fido Intelligence, Gdynia Innovation Centre, IVO Software, InteliWISE, Logotec Engineering, PLATINET, PayLane, Planet Soft- IT Outsourcing, TeleMobile Electronics, i3D (pozostałe z branżą IT są już raczej luźno powiązane - zwłaszcza producent skarpetek ;-) Dziwić może brak części znaczących producentów sprzętu jak choćby znanej w całej Europie firmy Wilk Elektronik SA (producent pamięci RAM marki GoodRAM). [CeBit]

poniedziałek, 2 marca 2009

Tip: Debugowanie zewnętrznej aplikacji

shrek-donkey-pick-me_1 Jak zdebugować zewnętrzny proces lub aplikację? Pick me, pick me, krzyczą wszyscy. Tak,  możemy to zrobić poprzez wywołanie Debug->Attach to process. Jest jednak inny sposób. Wyobraźmy sobie taką sytuację. Aplikacja kończy się wyjątkiem zaraz po jej uruchomieniu. Nie mamy nawet sekundy czasu na podczepienie się do procesu w ten sposób. Ale jest sztuczka :-)

Wywołujemy File->Open Project i wskazujemy plik .exe, który chcemy debugować. Klikamy F5 i Voila!

niedziela, 1 marca 2009

Firebug console.

firebug Jeśli jesteś programistą Web, to na pewno znasz dodatek do przeglądarki Firefox, a mianowicie Firebug. Jeśli go nie znasz, to MUSISZ go poznać. On powie Ci wszystko o tym co się dzieje z Twoją stroną.

Nie będę się skupiał na tworzeniu instrukcji obsługi tego dodatku, a skupię się na jego jednym z głównych elementów, czyli konsoli. Mam tutaj na myśli obiekt console, ktory jest globalnie dostępny na Twojej stronie dzięki Firebugowi, a być może do tej pory nie zdawałeś sobie sprawy o jego istnieniu.

Obiekt console jest typowym loggerem komunikatów, które służą w celach (głównie) debugowania aplikacji (więcej o logowaniu zdarzeń można przeczytać na moich poprzednich notkach). Wartości do niego przekazywane są widoczne bezpośrednio w okienku Fiebuga. Aby z niego skorzystać, wystarczy wywołać odpowiednią metodę. Jako parametry możemy przekazać dowolną liczbę obiektów (nazw zmiennych) oddzielonych przecinkiem.

console.log Wypisuje komunikat na konsoli Firebuga
console.debug Wypisuje komunikat wraz z linkiem do bloku kodu, który go wywołał
console.info, console.warn, console.error j.w. wraz z graficzną informacją typu komunikatu
console.trace Wypisuje stack trace wywołania kodu JavaScript. Wyświetla wartości parametrów funkcji.
console.assert Testuje czy podane jako argument wyrażenie logiczne jest prawdą
console.dir Wyświetla właściwości danego obiektu

Formatowanie komunikatów:

%s Jako ciąg znaków
%d, %i Jako liczba całkowita
%f Jako liczba zmiennoprzecinkowa
%o Odnośnik do obiektu

 

Przykład wywołania (kod javascript):

console.log("Zmienna: %s zawiera liczbę: %d", mojaZmienna, count);

console.log("Zmienna %s oraz wiele wartości:", mojaZmienna, war1, war2, war3);


Przykładowy efekt działania konsoli Firebuga:



screen_01 2009.03.01 21.21



Możliwości tego narzędzia są bardzo duże. Zdecydowanie jeden z moich ulubionych dodatków do FF. Pozdrawiam.

piątek, 27 lutego 2009

IoC oraz ASP .NET MVC

logo W tej notce postaram się przedstawić rozwiązanie pewnego częstego problemu z jakim spotykamy się podczas tworzenia aplikacji w modelu MVC.

Zapewne rzadko kiedy kontroler może obyć się bez dostarczenia mu obiektu reprezentującego repozytorium danych. Nieważne, czy jest to lista użytkowników, produktów, czy inna podobna inna lista, operacje na niej (choćby wyświetlanie danych) są wykonywane przez logikę biznesową zawartą właśnie w kontrolerze. Przyjmijmy, że chcielibyśmy zasilić nasz HomeController właśnie obiektem reprezentującym listę produktów. Jak tego dokonać? Jest kilka sposobów. Pierwszym z nich jest utworzenie własnego ControllerFactory. Jednak w naszym przypadku oprogramowanie zajęło by za dużo czasu :-)

Z pomocą przychodzi nam mechanizm IoC, który świetnie nadaje się do naszego MVC-problemu. Nie będę zajmował się tutaj wyjaśnianiem samego mechanizmu inversion of control, gdyż zakładam, że czytający ten tekst ma przynajmniej podstawowe pojęcie w tej dziedzinie. Ja wykorzystam do tego celu kontener Ninject.

Strategy pattern Zanim zaczniemy co kolwiek kodować warto rozejrzeć się "po okolicy" i zaplanować najlepszy sposób rozwiązania naszego problemu.

public class TestController : Controller 
{
  private ClientRepository _clientRepository;
  public TestController() {
    _clientRepository = new ClientRepository();
  }
  public void Add(string clientName) {
    _clientRepository.InsertNewClient(clientName);
  }
}


Powyższy fragment kodu (który na razie traktujmy jako pewien pseudokod) wydaje się być w miarę dobrym podejściem do utworzenia naszego repozytorium klientów. Podczas tworzenia kontrolera w jego konstruktorze powołujemy do życia obiekt typu ClientRepository i przechowujemy w prywatnej zmiennej.

Wady! Zdecydowaną wadą tego rozwiązania jest właśnie zależność. TestController ma zależność co do ClientRepository. Nie jesteśmy w stanie przekazać do naszej zmiennej repozytorium _clientRepository innego typu repozytorium, nawet gdyby ich kontrakt był taki sam (w przypadku repozytoriów często przecież tak jest) - bez zmiany kodu konstruktora: tightly coupled (ps. jak to przetłumaczyć? :-) ).


I dopiero po tak przydługim wstępie na scenę wchodzi StrategyPattern (w wolnym tłumaczeniu: wzorzec strategii).



strategy_simple 
Refaktoryzujemy nasz kod. Czas, aby wykorzystać wspomnianą bibliotekę Ninject.



Chcemy użyć mechanizmu wstrzykiwania przez konstruktor (oczywiście nic nie stoi na przeszkodzie aby zrobić to przez właściwość, czy metodę - jednak to już każdy w domu może sobie zrobić :-) ). Ninject ma kilka metod, które świetnie działają w połączeniu z kontrolerami. Ale po kolei. Pierwsze co musimy zrobić, to dodać dziedziczenie (w Global.asax) dla klasy MvcApplication z klasy NinjectHttpApplication.



public class MvcApplication : NinjectHttpApplication

Następnie przeciążamy dwie metody: RegisterRoutes oraz CreateKernel. Pierwsza z metod może być implementowana w taki sam sposób jak to było zaimplementowane dotychczas. Ważna jest wspomniana metoda CrateKernel.

protected override IKernel CreateKernel()
{
    IModule[] modules = new IModule[]
    {
 new AutoControllerModule("Testowa.Controllers"),
        new ServiceModule()
    };
    return new StandardKernel(modules);
}

internal class ServiceModule : StandardModule
{
    public override void Load()
    {
        Bind<Testowa.Controllers.IRepository>().To<Testowa.Controllers.ClientRepository>();
    }
}


Czyli po kolei: Tworzymy tablicę modułów (można to zrobić bez tablicy także). Za pomocą AutoControllerModule "przypinamy" się do zewnętrznej biblioteki klas kontrolerów znajdującej się w Testowa.Controllers. Ja preferuję wydzielenie kontrolerów do zewnętrznej biblioteki - jeśli jednak u Ciebie kontrolery znajdują się w tej samej assembly co aplikacja Web, to możesz użyć metody Assembly.GetExecutingAssembly() przekazanej jako parametr do konstruktora AutoControllerModule. Natomiast metoda Load naszego modułu binduje implementację interfejsu IRepository jako obiekt typu ClientRepository wszędzie tam, gdzie będziemy potrzebować typu IRepository.

Konsumpcja

Tworzymy nasz HomeController wiedząc, że wszystkie zależności automagicznie rozwiąże za nas Ninject. W tym celu w naszym przeprostym kontrolerze piszemy coś na wzór:



public class HomeController : Controller
{
    private readonly IRepository _service;
    public HomeController(IRepository clientRepository)
    {
        this._service = clientRepository;
    }
}


Zależności zostały zerwane, obiekty powoływane są do życia "same". Robimy sobie kawę.

poniedziałek, 2 lutego 2009

SharpArchitecture 1.0 Beta i ASP .NET MVC RC1

Ci który zdąrzyli zaktualizować środowisko ASP .NET MVC do wersji RC1 oraz używają SharpArchitecture w wersji 1.0 Beta, mogą być niemile zaskoczeni błędami podczas uruchomienia ich dotychczasowych aplikacji min. HttpUnhandledException.

Niestety SharpArch w wersji 1.0 beta nie współpracuje z wersją RC ASP .NET MVC i w momencie pisania tego artykułu rewizja kodu nr: 346 także nie wprowadzała tego bugfixu. Programiści trochę ociągają się z poprawianiem tego uniedogodnienia. Aby jednak nie rezygnować z projektów pisanych na nowej platformie należy poradzić sobie samemu :-) SharpArchitecture udostępniany jest jako projekt open source dlatego piersze co należy zrobić, to ściągnąć jego kody źródłowe, następnie otwieramy je:

  1. Aktualizujemy biblioteki MVCContrib: ja mam w wersji: 0.0.1.214
  2. Aktualizujemy biblioteki System.Web.Mvc , .Abstractions, .Routing
  3. Modyfikujemy plik WindsorExtensions.cs projektu SharpArch.Web.Castle następująco:
    1. Dodajemy using ControllerDescriptor = MvcContrib.ControllerExtensions;
  4. Modyfikujemy plik AreaViewEngine.cs:
    1. Dodajemy parametr useCache metody FindPartialView następująco: public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
    2. Refaktoryzujemy wszystkie wywołania w/w metody poprzez wprwadzenie parametru useCache
  5. Po przebudowaniu projektu dodajemy nowe pliki dll do naszego dotychczasowego projektu.

Pamiętajcie o przebudowaniu całości po wprowadzeniu zmian!

piątek, 30 stycznia 2009

Po XV spotkaniu PG.NET. Krótka relacja.

Parę słów na temat tego co działo się podczas 15 już spotkania: "Poznańskiej Grupy .NET".

Pierwsza prezentacja dotyczyła narzędzia XPO firmy DevExpress. Prezentacja prócz omówienia w.w. narzędzia była krótkim, ale wyczerpującym omówieniem najpopularniejszych graczy na rynku OR/Mappererów, min. NHibernate i EntityFramework. Samo rozwiązanie DevExpressa zaprezentowało się całkiem nieźle. Widać środki włożone w jego rozwój (wizardy, konfiguratory), których próżo szukać w projektach z którym pracuję w "piaskownicy" u siebie (głównie NHibernate). Ciekawe jest to, że wcześniej jakoś nie wiedziałem o tym rozwiązaniu, mimo że cenię sobie CodeRush-a tej samej firmy. Myślę, że temat OR/Mapperów powinien zostać pociągnięty dalej, gdyż dyskusje na temat wyższości jednych nad drugimi dało się słyszeć praktycznie cały czas :-) Fajnie by było, gdyby każdy przedstawił podejście do tematu (dostępu do bazy danych w ogóle) na własnym przykładzie, przykładzie firmy w której pracuje, podczas kolejnych spotkań PG.NET!

Prezentacja tycząca projektu OSLO także była ciekawa, choć to już była inna para kaloszy, w porówaniu z XPO. Dużo (i długo) się działo na ekranach pokazywanych przez Marcina. Pewnie wiele, jeszcze zostało do pokazania, ale najważniejsze jest to, że każdy mógł zaobaczyć troszkę inne podejście do projektowania systemów. Troszkę... całkiem inne! :-) Mimo, że przed OSLO jeszcze długa droga, to na pewno ten sposób modelowania znajdzie zastosowanie w życiu.

Jak zwykle można było się dowiedzieć wielu fajnych rzeczy i zgarnąć troszkę softu :-) Wieczór jak najbardziej udany!

środa, 28 stycznia 2009

PG.NET: XV Spotkanie, czwartek

W czwartek 29 stycznia o godz. 18:00. Bezpłatna rejestracja i pełna agenda znajduje się TUTAJ

Co na spotkaniu?

  1. Modelowanie rzeczywistości w OSLO by Marcin Kruszyński
  2. eXpress Persistent Objects na tle  innych narzędzi ORM by Michał Korsak

Nie warto tego przegapić! :-)

czwartek, 22 stycznia 2009

ASP .NET MVC & Membership

Wbrew pozorom wykorzystanie mechanizmu Membership And Role Providers na platformie ASP .NET MVC nie jest bardzo trudne.

Ja preferuję wykonanie do tego celu osobnego kontrolera (AccountController) oraz zaimplementowanie w nim metod służących do uwierzytelniania i autoryzacji użytkowników.

Przykładowy kod metody Login:

public ActionResult Login(string username, string password, bool? rememberMe)
        {
            ViewData["Title"] = "Login";
            // Non-POST requests
            if (Request.HttpMethod != "POST")
            {
                return View();
            }
            List<string> errors = new List<string>();
            if (String.IsNullOrEmpty(username))
            {
                errors.Add("You must specify a username.");
            }
            if (errors.Count == 0)
            {
                bool loginSuccessful = Membership.Provider.ValidateUser(username, password);
                if (loginSuccessful)
                {
                    FormsAuthentication.SetAuthCookie(username, rememberMe ?? false);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    errors.Add("The username or password provided is incorrect.");
                }
            }
            ViewData["errors"] = errors;
            ViewData["username"] = username;
            return View();
        }

Pozostałe metody implementujemy analogicznie pamiętając że zapytanie do nich powinno przyść w metodzie typu POST.