вторник, 24 июня 2008 г.

WPF Presentation layer

Я не буду блоггерствовать следующие 3 недели, но чтобы вы не расстраивались вот вам мой Presentation Layer.

В этом проекте реализован небольшой framework для разработки десктопных приложений на WPF с примерами, которые я уже выкладывал в предыдущих постах. В основном это реализация шаблона DM-V-VM.

В качестве бонуса я включил исходные коды Wizard контрола.

Наслаждайтесь.

среда, 11 июня 2008 г.

Enterprise logging system. Part 5. Features.

Как я уже говорил, в LogBook предусмотрены дополнительные фичи, позволяющие использовать его в самых различных сценариях. Например:

Сцена 1. Сервис. Действующие лица: WCF, LogBook.

Поскольку framework WCF черезвычайно легко расширяется, подключить LogBook к нему одно удовольствие. На тему расширения WCF очень хорошо написал Aaron Skonnard здесь. Так вот, LogBook расширяет WCF при помощи поведения сервиса, реализованного в виде аттрибута, который вы можете декларативно применить к любому WCF сервису. Что же добавляет это поведение? Оно добавляет ErrorHandler ко всем ChannelDispatcher'ам и MessageInspector ко всем DispatchRuntime'ам EndpointDispatcher'ов.

Таким образом соотвественно настроенный LogBook может логировать ошибки и трассировать сообщения, происходящие при работе сервиса.


ErrorHandler, вызывает метод WriteErrorMessage фасада LogBook.


MessageInspector, вызывает метод WriteTraceMessage фасада LogBook.

Сцена 2. DLinq. Действующие лица: DLinq, LogBook.
В DLinq предусмотрено подключение простого логгера, в который будут сваливаться все запросы, выполняемые системой. Этот логгер должен быть наследником TextWriter и переопределять как минимум метод Write(string). Для LogBook я написал простенькую реализацию, которая будучи подключенной к любому DLinq DataContext'у будет трассировать все запросы.


Linq tracer.

Сцена 3. .Net. действующие лица: System.Diagnostics, LogBook.
И последнее. Вы можете подключить LogBook к системе трассировки .Net при помощи простого TraceListner. Довольно удобно для приложений, код которых вам недоступен. С помощью этого прослушивателя трейсов вы сможете перенаправить сообщения в сервис логирования.



TraceListener.

Кроме того, в System.Diagnostics.Trace нельзя было передать контекст. А здесь можно.

Вот вкратце все сладости в LogBook. Жду предложений по дополнительным фичам!

Удачи!

вторник, 10 июня 2008 г.

Enterprise logging system. Part 4. Facade.

Ура, я проснулся от летаргического сна.

Предлагаю сразу взяться, например за дело.

Итак вперед.

В первой части я кратко описал требования к системе и архитектуру. В этой части я расскажу как эти требования были реализованы.

Самый очевидный способ интегрировать систему в свое приложение (о неочевидных я поговорю в следующий раз) это императивное использование ее в коде. Для данного сценария в системе предусмотрен простой фасад, которой за своей простотой скрывает тот объем работы, который необходимо проделать, чтобы гарантированно доставить сообщения в хранилище и удовлетворить всем предъявленным к ней (системе) требованиям.

Как вы помните в системе предусмотрено 5 уровней логирования:

  • Trace;
  • Info;
  • Warn;
  • Error;
  • Status;
, соответственно и интерфейс фасада определен количеством и именами этих уровней.

Что же скрывают за собой эти методы? Давайте рассмотрим работу LogBook по шагам.

При первом обращении к фасаду, прежде чем выполнить метод, clr будет вызван инициализатор типа. В этом статическом конструкторе LogBook пытается сконифигурировать себя. Этот процесс он делегирует статическому классу-загрузчику Bootstrapper, который сначала пытается получить настройки для текущего клиента от сервиса, а затем производит инициаллизацию хозяина (LogBook) из локального конфига (если вдруг в момент старта сервис будет недоступен, то он сможет поднять LogBook по локальным настройкам, которые сохраняются в конфигурационном файле клиента, а если не сможет, то кинет исключение).

Далее, в зависимости от уровня логирования LogBook создаст соответствующее сообщение и отправит его на валидацию в список подключенных фильтров (важно сделать это до окончательного заполнения сообщения, чтобы не тратить память и время зря, если оно не проходит по условиям фильтров). После этого, дабы не блокировать клиента, фасад LogBook делегирует отправку сообщения RequestManager'у, который в асинхронном режиме постарается отправить его куда следует. Куда следует - это сюда: первым делом он сохранит его в локальной стратегии, а затем попытается отправить его сервису. В случае неудачной попытки, он увеличит счетчик неудачных попыток, проверит условия устаревания сообщения (по времени хранения и количеству неудачных попыток) и сохранит обратно сообщение в локальную очередь, если оно все еще валидно. За подключением сервиса следит ConnectionMonitor, который при изменении статуса подключения генерирует событие, перехватываемое RequestManager'ом.

Все методы перегружены одним дополнительным параметром - контекстом, о котором я писал здесь. Если вызывается метод без котекста, или вместо него передается null, то в качестве контекста будет автоматически подставлен LogContext.Current.

Вот в очень сжатом виде механизм работы моего enterprise LogBook'а.

Подумываю завести проект на CodePlex. Займусь этим на досуге.

Удачи!

вторник, 3 июня 2008 г.

Handy Monitor wrapper.

Вам никогда не требовалось узнать, стоят ли за текущим потоком в очереди другие потоки на блокировке? Если да, то вы наверняка уже полазили по классу Monitor в поисках свойства, которое бы называлось как-нибудь вроде LockCount или Busy. И тогда-то вы уж точно знаете, что это "конфиденциальная информация"! =)

Ниже я привожу простой и удобный класс-обертку над Monitor, который предоставляет такую информацию совершенно бесплатно. И что самое прекрасное, блокировка также осуществляется с поддержкой языка (я имею ввиду синтаксические конструкции, которые позволяют писать элегантный код). Но есть небольшая разница, если блокировка Monitor осуществляется конструкцией lock(object) {}, то в данной реализации она осуществляется конструкцией using(object){}. Ниже код класса и пример.





Вот пример использования:



Удачи!

P.S. Реализацию я подглядел в недрах какой-то из системных сборок.