sobota, 29 listopada 2008

Tip: Jak pobrać tytuł strony www. Niezawodnie.

Jest kilka sposobów na odczytywanie dokumentów tekstowych i wyszukiwanie w nich określonych treści. Często najbardziej niezawodne jest użycie do tego celu wyrażeń regularnych, czyli inaczej mówiąc regexa. Oto przykład jak pobrać tytuł witryny:

public string GetHTMLPageTitle(string file)
{
    Match m = Regex.Match(file, @"<title>\s*(.+?)\s*</title>");
    if (m.Success)
        return m.Groups[1].Value;
    else
        return string.Empty;    
}

Może się przydać :-)

piątek, 28 listopada 2008

Relacja po XIII spotkaniu PG.NET

Kto nie był, niech żałuje. Po pierwsze gratulacje dla zespołu Cognifide za pokaz ich (chyba sztandarowego) dzieła: EpiServera CMS. O ile byłem troszkę sceptycznie nastawiony do prezentacji, gdyż nie liczyłem na nic odkrywczego, to po prezentacji byłem zaskoczony na plus! Bardzo dobry przykład wykorzystania technologii .NET w stworzeniu naprawdę dużego narzędzia bijącego moim zdaniem Sharepointa na głowę. Kilka mechanizmów EpiServer mnie nawet zainspirowało - przedewszystkim ten rozszerzalny framework.

Inauguracja PLSSUG i prezentacja Stefana rozwiała przede wszystkim mój niedawny problem. Druga sprawa, to fajnie jest być na bieżąco jeśli chodzi o SQL Servera. Prezentacja również jak najbardziej udana. Stefan to niezły geek sqlowy :-). Taaak rozumiem jak to jest kiedy się przychodzi do domu, a tu nikt nie wie o czym się mówi :-)

Podsumowując: kolejny udany wieczór z kodem :-)

poniedziałek, 24 listopada 2008

PG.NET: XIII spotkanie już w czwartek


Na czwartek proszę, aby każdy poznański (ale mile widziana cała Polska!) developer .Net zaplanował sobie wieczór tak, aby móc wybrać się na spotkanie PG.NET
Na szczęśliwej, trzynastej odsłonie zaprezentowany zostanie projekt: EpiServer CMS firmy Cognifide (Adam Najmanowicz) oraz (uwaga) wystartuje PLSSUG (Polish SQL Server User Group) Poznań (Stef Konopnicki)!!
Agenda i rejestracja dostępna jak zwykle na stronie grupy: http://ms-groups.pl/pg.net/default.aspx
Obecność obowiązkowa!

IT Academic Days na Politechnice Poznańskiej

Mam przyjemność zaprosić wszystkich programistów i nie-programistów na imprezę Microsoft IT Academic Days, która odbędzie się 4 grudnia w Centrum Wykładowym Politechniki Poznańskiej. ITAD to cykl akademickich wykładów na których można zobaczyć i usłyszeć wiele ciekawych informacji o technologiach i innowacyjnych rozwiązaniach firmy Microsoft, ale nie tylko. Będę miał na niej swoje "pięć" minut przedstawiając wykład pt. "Trzej muszkieterowie, czli ASP .NET MVC". Start imprezy o godzinie 9:00. Dostępna jest już pełna Agenda. Zachęcam wszystkich gorąco, mimo że zimno :-) !

Wstęp jest bezpłatny, po wcześniejszej rejestracji na portalu CodeGuru. Strona konferencji: http://itacademicday2008.studentlive.pl/

poniedziałek, 17 listopada 2008

Data jest data?!

Operacje na datach to pewnie chleb powszedni dla każdego programisty. Wstawianie ich do bazy danych, to kolejna, seryjna nasza czynność. W zasadzie bardziej chodzi mi o umieszczanie domyślnych wartości daty w tabelach bazy danych MS SQL Server. W sumie niebyłoby nic odkrywczego, gdyby nie fakt, że wyjątki w takim kodzie pojawiają się w najmniej oczekiwanych momentach :-)

Istnieje spora różnica między wartościami: DateTime.MinValue, który w rezultacie da: 01-01-0001, a SqlDateTime.MinValue, który zwróci: 01-01-1753. Cała zabawa powoduję, że podczas próby wstawienia rekordu, którego wartość w kolumnie typu DateTime jest generowana w kodzie programu przez DateTime.MinValue otrzymujemy wyjątek przekroczenia wartości. Dlatego, aby wstawić minimalną wartość typu DateTime do bazy danych należy zawsze posługiwać się SqlDateTime.MinValue.

Jeszcze ciekawsza systuacja jest przy porównaniu wartości: DateTime.MaxValue oraz SqlDateTime.MaxValue. Zróbmy proste zadanie: wstawmy do tabeli w naszej bazie danych wartość DateTime.MaxValue, potem odczytajmy tą wartość do zmiennej lokalnej tego samego typu. Na szybko naskrobałem coś takiego:

static void Main(string[] args)
{
    DateTime fromDb = DateTime.MaxValue;
    DateTime toDb = DateTime.MaxValue;
    SqlConnection conn = new SqlConnection(@"Data Source=TOSHIBA\SQLEXPRESS;Initial Catalog=Poligon;Integrated Security=True");
    try
    {
        conn.Open();
        SqlCommand cmd = new SqlCommand("INSERT INTO Daty VALUES(@data)", conn);
        cmd.Parameters.Add("data", System.Data.SqlDbType.DateTime).Value = DateTime.MaxValue;
        cmd.ExecuteNonQuery();
        SqlCommand getCmd = new SqlCommand("SELECT TOP(1) DAT_Data FROM Daty", conn);
        using (IDataReader rdr = getCmd.ExecuteReader())
        {
            while(rdr.Read())
            {
                fromDb = Convert.ToDateTime(rdr["DAT_Data"]);
            }
        }
        bool areSame = (DateTime.Compare(toDb, fromDb) == 0);
        TimeSpan subDates = toDb.Subtract(fromDb);
        int result = subDates.Milliseconds; //nasz wynik
    }
    finally
    {
        conn.Close();
        conn.Dispose();
    }
}

Że co?


Metoda DateTime.Compare nie zwróciła nam wartości 0 (zero), co oznaczałoby, że data zapisana do bazy i ta odczytana są takie same. Zwróciła nam wartość, która oświadcza nam, że wartość otrzymana z bazy danych jest mniejsza od tej, którą zapisaliśmy.


Zaglądamy do zmiennej result...


Zmienna result trzyma dla nas różnicę obu dat. Po odjęciu wartości otrzymanej z bazy danych od tej którą zapisywaliśmy dostajemy różnicę wynoszącą... dwie równiutkie milisekundy.


Prawie robi wielką różnicę


DateTime.MaxValue to: 31-12-9999 23:59:59.999, natomiast maksymalna wartość daty dla bazy danych, czyli to co zwraca SqlDateTime.MaxValue to: 31-12-9999 23:59:59.997 Różnica dwóch milisekund występuje w momencie konwersji DateTime do SqlDateTime, tu nie otrzymujemy wyjątku - a powinniśmy gdyż zakresy nieznacznie, bo nieznacznie, ale różnią się. Baza danych posłusznie przyjmuje wartość potajemnie ucinając 2 ms. Biednemu developerowi wydaje się że wszystko jest ok (bo narzędzia podglądu danych oraz debugger nie wyświetlają wartości z tak dużą precyzją). Pytanie za 100 punktów: co powodują taką różnice? Dlaczego nie można było tej wartości wydłużyć o te 2 nieszczęsne milisekundy?

Inspektor Gadget, czyli śledzenie aplikacji cz. III

NLog - projekt o polskich korzeniach!

Tak, tak - nie tylko prezydent USA ma polskie korzenie! Ma je także NLog, gdyż został napisany przez polskiego programistę: Jarka Kowalewskiego. Ale nie dlatego chcę przedstawić tą bibliotekę jako wartą wypróbowania. Jest to biblioteka, która z pewnością dostarczy nam wszystkich niezbędnych mechanizmów potrzebnych do logowania zdarzeń w naszych aplikacjach. Niestety aktualnie autor nie uczestniczy tak aktywnie w projekcie jak kiedyś.

Zanim przystąpimy do implementacji gorąco zachęcam do zapoznania się z poprzednim artykułem poświęconym log4net, a także wstępniakiem do całej serii Wystarczy, że jako czytelnik poznasz zasadę rejestracji zdarzeń w log4net, gdyż w NLog jest ona analogiczna.

Zaczynamy przygodę z NLog

Pierwsze co musimy zrobić, to ściągnąć binarki z oficjalnej strony projektu. Ja do celów tego artykułu wykorzystam wersję nlog-1.0-setup.exe. Dzięki tej paczce oprócz samych plików dll otrzymamy także dokumentację i zbiór przykładów. Po instalacji dodajemy referencję do NLog.dll znajdującym się w folderze net-2.0. Następnie do projektu dodajemy plik konfiguracyjny NLog.config - plik ten zostanie automatycznie wczytany i NLog z niego pobierze sobie konfigurację. Ustawmy mu właściwość "Copy to Output Directory" na: "Copy always". Wyjście naszych logów - o priorytetach: Debug wzwyż - będziemy kierować na konsolę, dlatego do pliku konfiguracyjnego powinniśmy dodać wpis: "targets".

<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target name="console" xsi:type="Console"
            layout="${longdate}|${level}|${message}"/>
  </targets>
</nlog>

Cel mamy zdefiniowany, teraz pora na definicję zasad: tak jak ustaliliśmy wcześniej interesuje nas jedynie logowanie zdarzeń o priorytecie Debug i wyższych. Dodajmy więc definicję rules poniżej definicji targets:


<rules>
    <logger name="*" minlevel="Debug" writeTo="console" />
</rules>

Sama zasada wstawiania zdarzeń do logów jest praktycznie identyczna jak w log4net. Pierwsze co musimy zrobić to otrzymać instancję klasy Logger. Robimy to wywołując statyczną metodę klasy LoggerManager:


using System;
using NLog;
namespace NLogSample
{
    class Program
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();
        static void Main(string[] args)
        {
            logger.Debug("Nasz pierwszy komunikat NLog!");
        }
    }
}

Po testowym uruchomieniu efekt powinien być podobny do poniższego:


nlog1


Ok, ale logowanie na konsolę to na pewno nie jest to, co docelowo chcielibyśmy osiągnąć. Spróbujmy zatem tym razem logować zdarzenia do pliku tekstowego: chyba jednej z czytelniejszej formy logowania zdarzeń (choć problem z filtrowaniem ich to inna sprawa). Aby nie niszczyć pracy jaką włożyliśmy w poprzedni przykład :-) nasza aplikacja do pliku tekstowego będzie logowała zdarzenia o priorytetach Error i wyższych, reszta niech idzie na konsolę, tak jak było to dotychczas. Dodajmy więc nową regułę do pliku konfiguracyjnego NLog.config:


<logger name="*" minlevel="Error" writeTo="file" />

Czas na dodanie wpisu konfiguracyjnego samego celu:


<target name="file" xsi:type="File"
            layout="${longdate} ${logger} ${message}"
            fileName="${basedir}/logfile.txt"
            keepFileOpen="false"
            encoding="iso-8859-2" />

Myślę, że poszczególne atrybuty są na tyle czytelne, że nie trzeba ich szerzej opisywać, ciekawskich odsyłam do dokumentacji :-) Po modyfikacjach plik NLog.config powinien wyglądać następująco:


<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target name="console" xsi:type="Console"
            layout="${longdate}|${level}|${message}"/>
    <target name="file" xsi:type="File"
            layout="${longdate} ${logger} ${message}"
            fileName="${basedir}/logfile.txt"
            keepFileOpen="false"
            encoding="iso-8859-2" />
  </targets>
  <rules>
        <logger name="*" minlevel="Debug" writeTo="console" />
        <logger name="*" minlevel="Error" writeTo="file" />
  </rules>
</nlog>

Czas na odrobinę kodu, przypominam dodajemy logowanie zdarzeń typu Error do pliku tekstowego:


using System;
using NLog;
namespace NLogSample
{
    class Program
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();
        static void Main(string[] args)
        {
            logger.Debug("Nasz pierwszy komunikat NLog!");
            int a = 1;
            int b = 0;
            try
            {
                int c = a / b;
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
        }
    }
}

Wystarczy nam teraz uruchomić aplikację i przekonać się, że w folderze ze skompilowanym programem został utworzony plik logu, w którym będą lądowały wyjątki przechwycone w blokach try-catch.
Oczywiście to dopiero ułamek potęgi biblioteki NLog. Oprócz jej niewątpliwej szybkości (sprawdzonej w kilku benchmarkach), należy odnotować mnogość celów dla zdarzeń, czyli:

• Class Description
• ASPNetTraceTarget 
• ChainsawTarget 
• ConsoleTarget 
• DatabaseParameterInfo
• DatabaseParameterInfoCollection
• DatabaseTarget
• DebuggerTarget
• DebugTarget
• FileTarget
• FormControlTarget 
• MailTarget
• MemoryTarget
• MessageBoxTarget
• MethodCallParameter
• MethodCallParameterCollection
• MethodCallTarget
• NetworkTarget
• NLogViewerTarget 
• NullTarget 
• RichTextBoxTarget
• TraceTarget 
• WebServiceTarget

Jako zadanie domowe mogę zachęcić Was do zalogowania zdarzeń do kilku innych wyjść.


środa, 12 listopada 2008

Tip: Możesz wywołać breakpoint nie ustwiając go w IDE

Witam :-)
Pewnie 99% przypadków zatrzymywania kodu w tzw. breakpoincie dokonywana jest przez oznaczenie odpowiedniej linijki kodu jako właśnie breakpointa, klikając na marginesie edytora kodu Visual Studio w linii w której ma nastąpić przerwanie. Istnieje jednak inna możliwość jego wywołania: programowa. Wystarczy wywołać: Debugger.Break(). Wcześniej należy zaimportować przestrzeń nazw System.Diagnostics.

Pilnie kupię Windows Vista ;-)

Przygoda z Windows Azure była niczym sen, który pewnego wieczora (jakieś 5 min temu) prysnął. Jestem jeszcze przedpotopowym developerem pracującym na... XP-ku. Chyba czas iść do sklepu... ehhh.

niedziela, 9 listopada 2008

Democamp Poznań. Targi startupów.

20 listopada 2008 w Pawilonie nr. 11 Międzynarodowych Targów Poznańskich odbędzie się impreza "Democamp", czyli targi przeznaczone dla startupów. Na targach, oprócz projektów, zagoszczą także spółki Venture Capital oraz będziemy mogli poznać działalność akademickich inkubatorów przedsiębiorczości. Impreza obowiązkowa dla wszystkich, który chcą zaistnieć w sieci wraz ze swoim projektem!

Źródło: http://democamp.pl/

sobota, 8 listopada 2008

Inspektor Gadget, czyli śledzenie aplikacji cz. II

log4net wchodzi na scenę

Podstawowymi klasami biblioteki log4net z jakimi będzie pracował programista są: LogManager oraz Log. LogManager pełni funkcję kontentera i zarządcy nad Loggerami. Cały system może składać się z hierarchii Loggerów – klas dostarczających metod do logowania. Aby otrzymać konkretną nazwaną instancję klasy Logger posługujemy się statycznymi metodami GetLogger obiektu LoggerManager.



Żądania logowania wykonywane są przez wykonanie określonej metody w zależności od typu zaistniałego zdarzenia, czyli: DEBUG, INFO, WARN, ERROR, FATAL
Zdarzenie zostanie zalogowane przez dany Logger jeśli ma taki sam lub wyższy priorytet. Z kolei każdy Logger może posiadać filtr w którym określono na zdarzenia jakiego typu (priorytetu) ma reagować. Jeśli do danego Loggera nadejdzie żądanie zalogowania zdarzenia niższego niż jest przez niego obsługiwane, to nie zostanie ono zalogowane. Warto zauważyć także, że każdy typ logów może mieć określony sposób formatowania, jest to szczególnie istotne zwłaszcza jeśli część z nich wysyłamy np. mailem w formacie HTML, a część logujemy w bazie w postaci czystego tekstu.

Konfiguracja log4net
Żaden system bez odpowiedniej konfiguracji nie może działać poprawnie. Na szczęście log4net dostarcza szeroki wachlarz możliwości konfiguracji zarówno przez pliki XML jak i programowo. Po pierwsze musimy pobrać log4net z witryny http://logging.apache.org/log4net/download.html i dodać referencję do jego głównej biblioteki log4net.dll. W niniejszym przykładzie będę posługiwał się wersją 1.2.10. Sam log4net nie wymaga wielkiego nakładu na jego konfigurację aby zaczął działać w swojej podstawowej formie. W zasadzie można powiedzieć, że domyślne ustawienia środowiska są wystarczające, aby zacząć przygodę z log4net i sprawdzić, czy w ogóle jest to warte zachodu :-)

using System;
using System.Collections.Generic;

using log4net;
using log4net.Config;

namespace ConsoleApplication1
{
class Program
{
private static readonly ILog MyLogger = LogManager.GetLogger(typeof(Program));

static void Main(string[] args)
{
BasicConfigurator.Configure(); //konfiguracja podstawowa, bez pliku xml
MyLogger.Info("Aplikacja została uruchomiona");

}
}
}



Aby zmusić log4net do pobrania swojej konfiguracji z pliku konfiguracyjnego aplikacji, programista musi jedynie stworzyć odpowiednie wpisy konfiguracyjne oraz wymusić załadowania nastawów z pliku. Spróbujmy dodać plik App.config i wypełnić go podobnie jak na schemacie poniżej.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="ConsoleAppender" />
</root>
</log4net>
</configuration>



Teraz wystarczy jedynie załadować konfigurację wywołując metodę XmlConfigurator.Configure();

Logujemy!

Stwórzmy prostą aplikację, która swoją konfigurację do logowania pobierze z pliku konfiguracyjnego aplikacji, a logi typu INFO oraz DEBUG umieszcza na konsoli. Pierwsze co musimy zrobić do dodać odpowiedni plik App.config. Ze względu na to, że w naszym systemie chcemy logować dwa typy zdarzeń: informacyjne (INFO) oraz debugowe (DEBUG) musimy stworzyć wpis appender, czyli naszego wyjścia. Wewnątrz wpisu appendera należy podać sposób formatowania pojedynczego wpisu logu.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="ConsoleAppender" />
</root>
</log4net>
</configuration>



Dostępne w log4net wyjścia dla naszych logów to:
• AdoNetAppender,
• MS SQL Server,
• MS Access,
• Oracle9i,
• Oracle8i,
• IBM DB2,
• SQLite,
• AspNetTraceAppender,
• BufferingForwardingAppender,
• ColoredConsoleAppender,
• ConsoleAppender,
• EventLogAppender,
• FileAppender,
• ForwardingAppender,
• MemoryAppender,
• NetSendAppender,
• OutputDebugStringAppender,
• RemotingAppender,
• RollingFileAppender,
• SmtpAppender,
• SmtpPickupDirAppender,
• TraceAppender,
• UdpAppender

Uważny czytelnik zauważył pewnie, że nie zdefiniowaliśmy celu naszych logów dla zdarzeń INFO. Tak jak wspominałem wcześniej zdarzenia mają określoną hierarchię i w przypadku wystąpienia zdarzenia o priorytecie >= zdefiniowanemu zostanie on na pewno obsłużony, a o niższym priorytecie - nie.
Wpis o priorytecie INFO jest nad wpisem DEBUG więc wyląduje na naszej konsoli. Podobnie stanie się z wpisami o priorytetach ERROR i FATAL - te akurat zdarzenia powinny być umieszczane w blokach try-catch i automatycznie gromadzić wyjątki np. w bazie danych. Po dokładną specyfikację priorytetów odsyłam do oficjalnej strony projektu log4net .
W systemie może istnieć tyko jeden logger główny: root, reszta logerów dziedziczą po nim tworząc swoiste drzewo dziedziczenia.

namespace ConsoleApplication1
{
class Program
{
private static readonly ILog MyLogger = LogManager.GetLogger(typeof(Program));

static void Main(string[] args)
{
XmlConfigurator.Configure();
MyLogger.Info("Aplikacja została uruchomiona");
If (args != null)
MyLogger.Debug(string.Format("Argumenty uruchomieniowe: {0}", args));
MyLogger.Info("Aplikacja została zakończona");
}
}
}



Efekt powinien być podobny do tego:



W ten oto sposób poprawnie skonfigurowaliśmy oraz zalogowaliśmy pierwsze zdarzenia za pomocą biblioteki log4net! Chyba nie było to trudne?

Do pobrania:

Tip: Jak przyśpieszyć uruchamianie projektu?

Istnieje pewna sztuczka w Visual Studio, która pozwala za skrócenie czasu uruchamiania się i budowania projektów. Kiedy plik solution składa się z wielu projektów, wystarczy zaznaczyć, aby budowany był jedynie projekt startowy oraz jego zależności.
Tools – Options – Projects and Solutions – Build and Run i zaznaczamy Only build startup projects and dependencies on Run

czwartek, 6 listopada 2008

Inspektor Gadget, czyli śledzenie aplikacji cz. I

Problem śledzenia działania aplikacji oraz eliminowania błędów jest tak stary jak stare jest programowanie. Pierwsze języki programowania nie posiadały rozbudowanych środowisk programistycznych oraz tak zaawansowanych technik śledzenia wykonywania kodu programu. Wraz z rozwojem samych języków, rozwoju ulegały także zintegrowane środowiska wytwarzania oprogramowania. Dziś chyba trudno sobie wyobrazić programowanie, a tym bardziej wyłapywanie błędów bez debugera.
Chciałbym przyjrzeć się w jaki sposób możemy najefektywniej śledzić działanie aplikacji oraz wychwytywać w nich błędy. Wszystko po to, aby nasze programy mogły działać jeszcze szybciej i bezbłędnie.

Podejście pierwsze – najprostsze
Chyba każdy z nas stosował lub nawet stosuje do dziś popularne wyświetlanie zawartości interesujących nas zmiennych na ekranie (konsoli). Popularna technika jest chyba najstarszą formą debugowania programów. Jej podstawową zaletą jest to, że bardzo łatwo ją zaimplementować oraz daje przejrzyste wyniki. Na tym chyba zalety się kończą. Wad jest sporo: kod służący do śledzenia kompilowany jest to programu wynikowego, trudno w nim śledzić bardziej zaawansowane powiązania z innymi zmiennymi itd.

Na szczęście takie podejście do problemu śledzenia aplikacji należy raczej do rzadkości, a metodologie dostępne dla każdego programisty dają znacznie lepsze rezultaty. Innym pewnym rozwinięciem przedstawionej wyżej techniki jest zapis stanu zmiennych do pliku tekstowego. To również popularna technika ze względu na łatwość zapisu do pliku w większości języków programowania. W dalszej części artykułu postaram się je przedstawić w jaki sposób za pomocą dostępnych narzędzi i bibliotek możemy podejść do problemu w bardziej zaawansowany sposób.

Biblioteki logowania
Czym są biblioteki programowania? Są to specjalizowane biblioteki stworzone po to aby programista nie musiał przejmować się samym sposobem wyświetlania, czy zapisu komunikatów diagnostycznych. Praca z nimi zazwyczaj sprowadza się do wywołania odpowiedniej metody, a biblioteka sama dba o odpowiedni przepływ komunikatów diagnostycznych. Należy w tym momencie nadmienić, iż powstał pewien podział na komunikaty diagnostyczne, które zostały oddzielone od komunikatów błędów. Często prowadzi to do innego (definiowanego przez programistę) zachowania się bibliotek logowania w przypadku wystąpienia błędu, a innego w momencie rejestracji informacji czysto diagnostycznych.
W Internecie istnieje wiele bardzo dobrych rozwiązań służących do tego celu. Najciekawsze z nich to:
1. log4net
2. NLog
3. Microsoft Enterprise Library Logging Application Block

Pierwsza z przedstawionych bibliotek jest portem doskonałej javowej biblioteki log4j. Posiada ona bogatą grupę projektów, które z jej rozwiązań korzystają oraz - co jest zaletą – jest dość dojrzałym i stabilnym projektem. Nie ma najmniejszych problemów z dostosowaniem przepływu raportowania, a lista celów naszych logów jest długa.
NLog został stworzony przez polskiego programistę: Jarosława Kowalewskiego . Zawiera wiele celi logowania oraz pozwala na bardzo szeroką konfigurację. Niestety projekt nie jest już tak dynamicznie rozwijany – w zasadzie można powiedzieć o jego wstrzymaniu, choć na oficjalnej stronie takich informacji nie znajdziemy. Nie zmienia to faktu, iż w obecnej formie projekt pozwala na wykonanie wszystkich popularnych operacji zarówno raportowania błędów jaki i informowania o stanie aplikacji.
W kolejnych częsciach artykułów będę starał się przedstawić jak z tych dobrodziejstw korzystać. Zapraszam do odwiedzania!
Nich kod będzie za Wami!

niedziela, 2 listopada 2008

CodeGuru: Wykład pt. "ASP .NET Ajax"



Chciałbym wszystkich zaprosić na mój wykład, który odbędzie się 4 listopada 2008 r. na Politechnice Poznańskiej, a na którym będę starał się przedstawić wstęp do "ASP .NET Ajax". Spotkanie to odbywa się w ramach studenckich grup .Net.
Rejestracja na spotkanie jest możliwa przez portal CodeGuru.pl pod adresem: http://codeguru.pl/Default.aspx?Page=Events/ShowEventDetails&eventId=1814

Dodano: 04.11.2008
Przykłady oraz prezentacja (mirror na CodeGuru.pl):