Feel Good.

30 декабря 2010

Строим идентификатор для множества

Вчера вспомнил про одну интересную задачу, в которой необходимо было построить ключ для множества. Задача заключалась в построении коммутативного оператора над множеством, причем результат операции должен быть уникален для каждого множества.

Сформулируем требование следующим образом: найти такой оператор F, что для любого набора (u, v, ...) будет выполнено:
F(u, v, ...)= F(v, u, ...)=F(всевозможные перестановки) (условие коммутативности), причем не существует любого другого элемента z != u, такого что выполняется:
F(u, v, ...)=F(z, v, ...)=F(всевозможные перестановки) (условие уникальности)*.
Или более привычно: u, v, ... являются простыми ключами, а F(u, v, ...) составным ключом в единственном числе.

22 декабря 2010

Используем Reflection в T4 (Text Template Transformation Toolkit)

Недавно, мне была поставлена следующая задача: для каждого класса из стороннего API, разработать обертку (wrapper class), для удобства использования стороннего API. Оптимальное решение подобных задач всегда использовать кодогенерацию, а наиболее удобный инструмент для этого, это T4 (Text Template Transformation Toolkit). Так как набор классов находился в уже скомпилированной сборке, то действовать надо было только через System.Reflection. Как выяснилось позже, что при работе со сборкой через reflection в T4 возникает проблема блокировки, загружаемой через Assembly.Load, сборки. Stackoverflow подсказал, что для решения данной проблемы нужно воспользоваться FxCop API, предоставляющий достаточный инструментарий для работы со сборкой на уровне Reflection.

17 ноября 2010

False sharing

Казалось бы, зачем задумывываться о процессах, происходящих на таком низком уровне, как кэширование данных в L1 и L2 кешах (L1, L2 cache), если Вы программируете под .NET. Очевидно для повышения быстродействия программы (perfomance) за счет уменьшения кэш-промахов (Cache Miss). Самый простой и классический пример демонстрирующий проблему Cache Miss, это "неправильный" обход массива. При "правильном" обходе количество промахов будет минимально, следовательно участок кода выполнится быстрее:

int size = 10000;

int[,] matrix = new int[size, size];

 

// Вариант 1

// Очень медленный вариант

for (int col = 0; col < size; col++)

    for (int row = 0; row < size; row++)

        matrix[row, col] = 0;

 

// Вариант 2

// Быстрый вариант

for (int row = 0; row < size; row++)

    for (int col = 0; col < size; col++)

        matrix[row, col] = 0;


29 октября 2010

Настройка логов на примере NLog

Хочу поделиться с Вами своим best practices по настройке логирования на примере NLog. Логи, это первая вещь, которую приходится настраивать при создании нового проекта, причем обычно для каждого нового проекта настройки логирования выглядят, как шаблонное решение, поэтому разумно выделить единый общий шаблон и использовать его в своих проектах. В данной статье рассмотрим мое простое шаблонное решение, которое я успешно применяю во многих своих проектах. Основная идея которую я отразил в шаблоне, это ведение не одного общего лога, а нескольких, каждый из которых лишь отличается уровнем подробности логирования и назначением, это 2 основных и 2 вспомогательных лога.

06 октября 2010

Пишем обертку для Stopwatch

Во время работы приложения, в качестве мониторинга времени выполнения метода или доступа к свойству используется класс Stopwatch из System.Diagnostics. Работает Stopwatch очень просто, он замеряет время прошедшее между вызовами Start* и Stop* методами. Приведу простой пример:

// Наш секундомер.

Stopwatch timer = new Stopwatch();           

timer.Start(); // Запустим секундомер

try

{

    Thread.Sleep(1234); // долгая операция

}

finally

{

    timer.Stop(); // Остановим секундомер

    // Показания секундомера:

    TimeSpan elapsed = timer.Elapsed;

    Console.WriteLine("Время выполнения {0}", elapsed);

}


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

24 сентября 2010

Шаблон реализации Equals

Работая с объектами, нам часто явно или неявно приходится их сравнивать их друг с другом. За сравнение объектов отвечает метод Equals или его типизированная версия из IEquatable, возвращающая true в случае если объекты равны, в противном случае false. Стандартная реализация метода Equals не всегда удовлетворяет потребностям разработчика, так как она не учитывает конкретных особенностей объекта, и в этом случае, реализация конкретного Equals/IEquatable ложится на плечи самого разработчика. Каждый разработчик вправе по-своему реализовать данную функциональность (не нарушая правил Implementing the Equals Method), как ему будет удобно. У меня, как у разработчика, на этот счет со временем выработался удобный шаблон реализации метода Equals/IEquatable, состоящий из 2-х простых правил:
  1. От простого к сложному: выполнять сравнение начиная с простых условий и заканчивая более сложными.
  2. Понять равенство/неравенство объектов как можно раньше: делайте незамедлительный "return true/false".

31 августа 2010

Enum поле в XML API

Проектируя публичное API очень важно понимать, что Ваше API будут использовать другие разработчики различного уровня, которые будут вынуждены разбираться в нем с нуля. Именно поэтому важную роль здесь играет простота и понятность созданного Вами API. Интуитивно-понятное API намного проще осваивать, и тем более использовать. Любое API подразумевает обмен сообщениями между "клиентом" и "сервером", и зачастую такие сообщения удобно записывать в виде XML. Стандартная ситуация, Вы формируете некий XML и посылаете его на сервер, сервер разбирает его и отвечает Вам другим XML (XML API). К примеру, это может быть запрос аутентификации:

<request>

    <auth>

        <login>ilya</login>

        <password>*****</password>

    </auth>

</request>


и соответственно ответ на запрос со стороны сервера будет выглядеть следующим образом:

<response>

    <result>42</result>

 

    <!-- Остальные поля ответа... -->

</response>


05 августа 2010

Marker Interface против Custom attributes

Бывают случаи, когда у разработчика C# возникает острая необходимость пометить некую сущность маркером (Marker), и в зависимости от типа маркера соответственно обрабатывать сущность. Например, Вы получаете сообщения, и для различных типов сообщений (но не для всех, а например только для типа MessageB) делаете запись в лог о их получении (например, в методе OnReceive(Message msg)):

class Message{}

class MessageA : Message { }

class MessageB : Message { }

class MessageC : Message { }


03 августа 2010

NQueueing - Система Массового Обслуживания

Хочу представить Вам свою миниатюрную библиотеку (NQueueing), упрощающая C# .NET разработчикам процесс разработки приложений, в которых присутствует многопоточная обработка очередей (Система Массового Обслуживания (СМО)). Библиотеку NQueueing можно скачать с nqueueing.codeplex.com как в виде исходников, так и в виде готовой сборки.

22 июля 2010

Раcширяем IDisposable

Наверняка Вы сталкивались с ситуацией, когда Вам требуется совершить явный вызов метода Dispose у объекта, реализующего интерфейс IDisposable, при этом, для каждого такого Dispose-вызова приходиться постоянно писать одинаковый код, по следующему шаблону (проверка на null, вызов IDisposable.Dispose):

// Освобождение ресурсов

if (some != null)

{

    some.Dispose();

}


17 июня 2010

Блок using и null object

Интересное поведение наблюдается, если в блоке using используется нулевой объект: using(null){...}. Казалось бы, очевидно, у нас должно возникнуть исключение NullReferenceException при попытке вызвать метод Dispose нулевого объекта (null object), как только мы выйдем за пределы блока using:

using ((IDisposable)null)

{

}

// Исключения NullReferenceException не будет.

// Метод Dispose вызван не будет.


03 июня 2010

Enum как результат

Иногда, бывает очень удобно возвращать результат работы сервис-метода в качестве Enum значения. Представим ситуацию: Вы пишите сервис-метод, который возвращает два возможных состояния true/false (область значений), как бы Вы поступили, ограничились бы стандартным типом Bool или все-таки ввели бы новый Enum? Идея оставить Bool не совсем удачна, если вдруг придется расширить область значений сервис-метода. Например, в задаче аутентификации пользователя, где помимо информации об удаче/неудаче необходимо указать, в чем состоит неудача аутентификации, в итоге получим 4 возможных результата: "успех" (Ok), "провал" (Fail), "логин не верен" (LoginIncorrect), "пароль не верен" (PasswordIncorrect):

// Результат аутентификации

enum LoginStatus

{

    // Успех

    Ok = 0,

    // Провал

    Fail = (2 << 1),

    // Уточняем, в чем провал:

    LoginIncorrect = (2 << 2),

    PasswordIncorrect = (2 << 3)

}


27 мая 2010

XML elements или XML attributes

Всегда проектируя структуру XML файла, Вы наверняка задумывались, где хранить данные: в атрибуте (XML attribute) или все-таки в узле (XML element). Это довольно важный вопрос, который нужно решить раз и навсегда еще на этапе проектирования XSD схемы, иначе последующее переделывание XSD схемы не есть хорошая практика. Обратите внимание на два XML файла:

<?xml version="1.0" encoding="utf-8" ?>

<!-- Храним данные в атрибуте -->

<root>

    <child data="some data"></child>   

</root>

 

 

<?xml version="1.0" encoding="utf-8" ?>

<!-- Храним данные в узле -->

<root>

    <child>

        <data>

            some data

        </data>

    </child>

</root>


14 мая 2010

Thread-safe events

Если Вы пишите многопоточное приложение, то всегда стоит задумываться о потоко-безопасности (thread safe). Сегодня затронем важную тему про то, как правильно возбуждать событие (event raise), доступ к которому осуществляется в нескольких потоках.

class SomeClass

{

    // Доступ к данному событию происходит

    // в нескольких потоках.

    public event EventHandler SomeEvent;

}


Стандартный, потоко-безопасный (thread safe) шаблон вызова события выглядит следующим образом:

// Потоко-безопасный вызов.

public void OnSomeEventThreadSafe(EventArgs args)

{

    // Очень важно, сделать копию события:

    EventHandler handler = SomeEvent;

 

    // И далее работать только с ней:

    if (handler != null)

    {

        handler(this, args);

    }           

}


11 мая 2010

Совместное использование Repository с Unit Of Work.

В этом посте я решил поделиться мыслями о том, как можно применить паттерн Repository совместно с паттерном Unit Of Work (UOW). Рассмотрим это на конкретном примере. Для этого введем две сущности: Customer и Order, состоящим в отношении один-ко-многим соответственно.

04 мая 2010

Domain-Driven Design: создание домена

На днях прочитал полезную статью от Александра Бындю Domain-Driven Design: создание домена, подумав, я решил поделиться своим мнением и рассказать о том, как обычно разворачиваю домены в своих проектах, в частности рассказать о том, как для этого можно задействовать Entity Framework.

29 апреля 2010

Hello, Unity 2.0

Рассматривая ранее принцип инверсии зависимости, мы остановились на том, что нам нужен некий IoC/DI фреймворк, который помог бы нам избавиться от рутинной работы. Как я уже говорил, существуем множество различных IoC/DI фреймворков:
  1. Microsoft Unity
  2. Ninject
  3. Autofac
  4. StructureMap
  5. Castle
  6. Spring.Net
В этой статье мы познакомимся с open-source IoC/DI контейнером от Microsoft Unity 2.0 под .NET 4.0. Работать с данным фреймворком очень легко, и я продемонстрирую это Вам на простом примере, проделав простых 5 шагов:
  1. Создадим новый проект и добавим в него основные сущности. Смотри предыдущую статью.
  2. Скачаем необходимые библиотеки.
  3. Добавим references на них в проекте.
  4. Настроим IoC-контейнер через конфигурационный XML-файл.
  5. С помощью IoC-контейнера получим экземпляр объекта нашего класса.

26 апреля 2010

Используем Fluent Builder

Продолжая тему Fluent interface, решил написать про Fluent builder. Основная цель Fluent builder - упростить процесс конструирования объектов, используя для этого цепочки методов (set-методы).

20 апреля 2010

Extension Methods как «Синтаксический сахар»

Решил начать собирать на этой страничке интересные и полезные решения на базе Extension Methods, которые облегчают процесс написания кода, или другими словами «Синтаксический сахар».

16 апреля 2010

Используем Fluent Filters

В этой статье я хотел бы рассказать про очень элегантное решение получении выборок с помощью Fluent Filters, основная идея которого заключается в построении цепочки методов, называемые фильтрами, для искомого набора данных. Под набором я буду подразумевать объект типа IQueryable (IEnumerable). Цель Fluent Filters - свести процесс создания сложного фильтра к процессу композиции нескольких более простых фильтров, причем композиция фильтров реализована в форме Fluent interface.

14 апреля 2010

Используем процессор шаблонов. NVelocity.

В этой статье я расскажу о том, как можно решить проблему создания представлений для моделей, используя NVelocity. Классическая задача программиста: имея бизнес объект(Model) необходимо построить для него представление(View). При решении подобной задачи, требуется помнить о том, что для конкретной модели может быть несколько представлений, в то время, как модель даже о них и не догадывается. На сегодняшний день существует несколько известных View Engine:
  • System.Web.Mvc.WebFormViewEngine
  • Brail
  • NDjango
  • NHaml
  • NVelocity
  • Spark View Engine

13 апреля 2010

Аутентификация по OpenID в ASP.NET MVC

В этой статье я хочу поделиться с Вами опытом разворачивания инфраструктуры OpenID в ASP.NET MVC приложении. По тексту я создам простое ASP.NET MVC приложение, поддерживающее аутентификацию клиента по OpenID. Точнее сама аутентификация будет проходить на стороне OpenID провайдера, который, относительно нашего приложения, выступает в роли подтверждающей стороны владения данным OpenID. Что такое OpenID и зачем он нужен можно найти здесь. Существует несколько видов аутентификации, но мы рассмотрим наиболее распространенный - checkid_setup. На пути достижения нашей цели выделим несколько этапов:
  1. Получение OpenID аккаунта.
  2. Установка API DotNetOpenAuth.
  3. Создание тестового проекта на ASP.NET MVC.
  4. Запуск и тестирование.

09 апреля 2010

User Stories или чего хочет пользователь

Переход на User Stories это первый шаг на пути к Agile software development. User story это атомарное требование к программному продукту, записанное в виде одного, двух предложений, сформулированное пользователем (заказчик или клиент) на простом языке и прежде всего сфокусированное на то, чего хочет пользователь.

08 апреля 2010

Arrange-Act-Assert

Использование шаблона Arrange-Act-Assert (AAA) при написании unit тестов, намного повышает шансы других разработчиков понять Ваш код. Наверняка Вы уже использовали AAA в своих проектах, но не догадывались об этом. Давайте разберемся, что же это за шаблон. Итак, все просто, данный шаблон всего лишь разделяет и группирует код теста на 3 секции, придавая, удобную для чтения, структуру unit теста:
  1. Arrange - выставление начальных условий.
  2. Act - отработка тестируемого функционала.
  3. Assert - сверка ожидаемых значений с полученными.

05 апреля 2010

Аутентификация. WCF

Аутентификация клиента на стороне WCF сервиса - одна из важнейших задач при разворачивании безопасности на WCF сервисе, позволяющая ответить на главный вопрос "КТО?". В этой статье я расскажу, как я реализовывал аутентификацию клиента на стороне WCF сервиса. Наша конечная цель: развернуть WCF сервис, реализующий интерфейс ISecretService, содержащий метод GetSecretCode, доступ к которому разрешен только аутентифицированным клиентам.

04 апреля 2010

Смотрим логи. NLogViewer

Однажды, я написал статью, в которой рассказал про то, как быстро начать работать с системой логирования NLog. Да, все это хорошо, мы умеем вести лог файл, но что с ним делать? Этот, правильный на мой взгляд, вопрос мне задавали мои читатели. И я решил рассказать о NLogViewer - системе анализа лог файла, созданным NLog. Вообще, лог файл не зависит от системы логирования, поэтому существует множество различных систем просмотра(анализа) лог файлов. В этой статье я расскажу о NLogViewer, и о том, как сделать связку NLog+NLogViewer.

31 марта 2010

Создаем сертификаты: OpenSSL

Практическая польза данной статьи, научиться быстро начать работу с SSL сертификатами при помощи программы OpenSSL. Разумеется, выпуском сертификатов занимаются специальные центры сертификации, и Вам не стоит задумываться о тонкостях создания сертификатов, тем более в production версии Вы все равно сделаете запрос на сертификат в один из таких центров, но в режиме debug/test, вы можете использовать сертификаты сделанные собственноручно (что мне однажды и потребовалось). Я не буду рассказывать что такое SSL сертификат и для чего он нужен, но для понимания статьи, это необходимо знать. Для лучшего понимания данной статьи, выделим несколько основных этапов:
  1. Скачаем и установим OpenSSL.
  2. Настроим рабочее место.
  3. Выпустим CA сертификат и для него список отозванных сертификатов CRL.
  4. Сделаем запрос на сертификат нашему центру сертификации.
  5. Выпустим сертификат по запросу.
  6. Добавим наши сертификаты в хранилища сертификатов.

29 марта 2010

Obsolete код

Наверняка Вы сталкивались с ситуацией, когда Ваш код устаревал и, например, если Вы пишите код в команде, то как проще всего сказать другим разработчикам, что Ваш код устарел? Да, просто пометьте его атрибутом Obsolete.

26 марта 2010

Sandcastle - генерируем документацию

В предыдущей статье, я рассказал о возможностях XML-документации и привел простой пример XML-документирования исходного кода, теперь пора научиться получать заветную документацию в удобном для чтения виде, разумеется, генерировать документацию будем автоматическими средствами Sandcastle.

22 марта 2010

XML-документация

Когда вы программируете, помните, что код пишется людьми для людей, а компилятор проглотит любой синтаксически правильный код. Согласитесь, что код с комментариями намного проще понять, а библиотеку с документацией намного удобнее использовать. Представьте ситуацию, перед Вами поставлена задача: поддерживать техническую документацию проекта в актуальном состоянии. Подумав, вы понимаете, что поддерживать её вручную с ростом проекта будет все сложнее и сложнее, поэтому приходите выводу, что оптимальным решением будет использовать автоматические средства генерации документации, но для этого, Ваши комментарии должны быть представлены так, чтобы их было бы удобно обрабатывать(только не надо изобретать велосипеды)... XML!

10 марта 2010

Hello, Mock

Во время разработки(тестирования) иногда возникает потребность использовать некий интерфейс, до того, как он будет реализован. Решением данной проблемы является использование Mock-объектов.

02 марта 2010

Hello, NUnit

Тестирование собственного кода - признак хорошего тона, а наличие Unit тестов - еще и признак профессионального подхода.

25 февраля 2010

Hello, NLog

Логирование - неотъемлемая часть любого проекта. Не секрет, что каждый из нас, хотя бы раз написал свою собственную систему логирования. А задумывались насколько она у Вас гибкая? Начиная новый проект, вы снова пишите новую систему логирования? До сих пор используете Console.WriteLine(...) в качестве ведения лога? Вывод один, используйте готовый logging framework, например: log4net, NLog, Logging Application Block от Microsoft и другие. Преимущества готовых logging framework-ов от самодельных:
  1. Гибкая настройка лога.
  2. Широкие возможности.
  3. Наличие конфигурационных xml-файлов с xsd-схемами.
  4. Готовое стабильное решение (экономия времени на отладке).
  5. Наличие документации (форумов, блогов).
У каждого из них есть свои плюсы и минусы. В статье мы познакомимся с одном из них - NLog.

16 февраля 2010

Об Exception в блоке using

Работать с исключениями всегда надо предельно внимательно, особенно если его следует ожидать внутри блока using.

04 февраля 2010

Принцип инверсии зависимости

Что такое зависимость? Задавались ли Вы вопросом, как много зависимостей присутствует в Вашем проекте? Для начала проясним ситуацию и определим понятие зависимость. Представьте ситуацию: есть 2 класса, один(X) из которых использует другой(Y), например делает вызовы методов - это и есть зависимость одного от другого (X от Y).

27 января 2010

Интерфейс, Каркас, Реализация

Любой проект, как правило, имеет некоторую архитектуру, которая определяется разбиением проекта на отдельные компоненты и связи между ними, где каждый компонент является логически законченным модулем. В таких проектах качество кода напрямую зависит от выбранной архитектуры. При неправильном подходе к выбору архитектуры растущего проекта, можно наблюдать превращение его в "снежный ком" или "спагетти", который невероятно сложно будет тестировать и модифицировать, а сам код будет вызывать у Вас отвращение и нежелание работать. Часто бывает, что забываешь про архитектуру, и начинаешь писать код, который умеет "делать все" но при этом имеет жесткие связи между компонентами, а в случае, если мы используем стороннюю библиотеку, то и жесткую завязку на ней. Попробуйте представить, как будет ориентироваться новый член команды в таком проекте? Или во сколько Вам обойдется, переход с одной библиотеки на другую, в случае если Вы откажетесь от текущей? Во избежание подобных проблем, возьмите за правило, прежде чем писать код, продумайте будущую архитектуру, а код Вы всегда успеете написать.

19 января 2010

15 января 2010

Именование пространств имен в XML, XSD

В своих проектах я использую, на мой взгляд очень удобную схему именования пространств имен в XML, XSD документах.