-->

понедельник, 24 августа 2015 г.

WcfStorm - тестовый WCF клиент на стероидах



В этом посте я поделюсь радостью от использования замечательной утилиты WcfStorm. Но, обо всем по-порядку.
Многие, работающие с WCF, сталкиваются с задачей оперативного тестирования веб-сервисов. Конечно, запустить Visual Studio, сгенерировать прокси и написать пару тестовых методов - это беспроигрышный вариант, но при работе с десятками сервисов такой подход грозит огромными потерями времени. Да и Студии в нужный момент может просто не быть под рукой.
Microsoft предлагает использовать для подобных задач программу WcfTestClient, входящую в состав Visual Studio, но целый ряд функциональных ограничений не позволяет использовать эту утилиту в реальных проектах. К примеру, на моем текущем проекте используются HTTPS привязки, а также авторизация через логин/пароль - и всё это не поддерживается в WcfTestClient! Да и по уровню usability эта утилита находится на уровне студенческой поделки.

То ли дело WcfStorm:

  • поддержка всех привязок, кроме webHttp;
  • поддержка Security;
  • дружественный UI;
  • сохранение/загрузка конфигураций;
  • нагрузочные тесты и многое другое!

При всем этом использовать утилиту очень просто: вбиваешь ссылку - клиент готов к работе. Долой рутину! WcfStorm высвобождает время разработчика для более важных дел. Советую попробовать каждому, работающему с WCF.

суббота, 22 августа 2015 г.

Exception.ToString() - в чем твоя проблема?

Сегодня я бы хотел поделиться своей болью: архитектурный изъян в реализации метода Exception.ToString() приводит к потере части информации для некоторых вложенных  исключений. Всем известно, что данный метод выводит Message + StackTrace самого исключения и всех вложенных. Например, следующий код:
var exception = new FileNotFoundException("error message", "filename");

Console.WriteLine(exception.ToString());
Выведет на консоль:
System.IO.FileNotFoundException: error message
File name: 'filename'
Теперь вложим наше исключение в другое:
var exception = new FileNotFoundException("error message", "filename");

var outerException = new Exception("outer message", exception);

Console.WriteLine(outerException.ToString());
Результат:
System.Exception: outer message ---> System.IO.FileNotFoundException: error message
 --- End of inner exception stack trace --- 
Заметили? Где имя пропавшего файла?

среда, 19 августа 2015 г.

Шаблоны Т4 - генерация любого текста (кода) в Visual Studio

На днях возникла потребность автоматизировать одну рутинную, регулярную задачу в рабочем проекте, суть которой сводится к генерации новых классов по уже имеющимся и написании методов-оберток для имеющихся методов по одному и тому же шаблону. Первый подход, который пришел в голову - это генерация кода посредством Т4-шаблонов в Visual Studio.  Пригодность подхода оценивалась по следующему тестовому заданию:
Имеется пространство имен (без вложенных подпространств), в котором находится ряд классов (и, возможно, других типов). На основе набора публичных свойств каждого класса, необходимо сгенерировать соответствующие классы-DTO. Типы свойств могут быть как встроенными типами CLR, так и классами из этого же пространства имен.
Грубо говоря, генерируем DTO по каждому заданному классу. С помощью Reflection с последующим выводом на консоль, задача решается за чашку чая. Перенести готовый код в *.tt файл тоже нетрудно - в данном случае, достаточно заменить вызовы Console на соответствующие вызовы класса GeneratedTextTransformation (о нем чуть ниже), а также прописать в *.tt файле все используемые сборки и пространства имен.

суббота, 8 августа 2015 г.

Optimistic concurrency в EF + SQL Server

К написанию этого поста меня подтолкнуло большое количество гайдов по Entity Framework, в которых задача реализации оптимистического конкурентного доступа (бррр! далее просто optimistic concurrency) сводится к добавлению столбца с типом rowversion (timestamp) в БД, либо использованию атрибута ConcurrencyCheck на интересующих полях класса. Идея такого подхода достаточно проста: выбранные поля будут включены в раздел WHERE инструкции UPDATE. Зачем? Рассмотрим простейший случай:

Получение данных из БД -> Изменение данных -> Сохранение в БД.

Если между загрузкой и сохранением данные в БД были изменены другим потоком/процессом, EF сможет определить конфликт, сравнив версии строк таблицы (если используется rowversion) либо попарно сравнив значения свойств, помеченных ConcurrencyCheck. В результате мы получим исключение, а данные в БД сохранены не будут. Причем, даже объявлять транзакцию в явном виде не нужно (хорошая идея, ага).

Это здорово - иметь optimistic concurrency из коробки, и формально не зависящее от БД. Но будем откровенны: наиболее популярное СУБД в одной упряжке с EF - это SQL Server, а процент проектов, где смена СУБД допускается хотя бы в перспективе - исчезающе мал. Так почему бы не воспользоваться средствами SQL Server? Конечно же, я говорю об уровнях изоляции SNAPSHOT и READ COMMITTED SNAPSHOT. У меня бы не получилось рассказать об изоляции транзакций лучше, чем у авторов моей любимой Microsoft SQL Server 2012 Internals, поэтому не буду и пытаться. Попробуем сравнить подходы EF и SQL Server к реализации optimistic concurrency.

воскресенье, 26 июля 2015 г.

Заметки на полях: конкурентный доступ в SQL Server

Полагаю, многие разработчики, потратив кучу времени на изучение и систематизацию определенной области знаний, оставляют заметки со списком полезных источников и своими комментариями. И я не исключение. Бывает так, что поставленная проблема разрешена, и применение накопленных знаний какое-то время не требуется. Поэтому такие заметки сильно помогают при необходимости быстро освежить свои знания, когда различные детали и тонкости реализации уже выветрились из кратковременной памяти. Дабы повысить качество подобных записей - я решил попробовать публиковать их. Теперь просто накидать десяток ссылок в Evernote и забыть про них не получится. Надеюсь, заметки перестанут теряться среди сотен других и забываться, а я не буду лениться их делать.
Тема, с которой я хотел бы начать - это уровни изоляции транзакций, блокировки, и pessimistic/optimistic concurrency в SQL Server (нет, я не DBA и не планирую им быть). Attention! Все ниже перечисленное - относится не к книгам целиком, а только лишь к их соответствующим разделам по конкурентному доступу.


Ицик Бен-Ган. Microsoft SQL Server 2008/2012. Основы T-SQL
Принципиальных различий между книгами этого автора для 2008 и 2012 SQL Server немного. Для книг Ицика Бен-Гана характерен легкий, удобочитаемый стиль изложения. Различия уровней изоляции показаны на простейших примерах, для выполнения которых достаточно SSMS. В то же время, информация в книге дана скудная и неполная - например, не рассмотрен update lock. Пожалуй, с этой книжной серии можно начинать знакомство с concurrency в SQL Server, но для знакомых с темой людей она почти бесполезна.


Душан Петкович. Microsoft SQL Server 2012. Руководство для начинающих
В разы больше информации о блокировках. Примеры далеко не так информативны и понятны, в том числе из-за постоянного использования инструкции WAITFOR. В целом уровень изложения чуть выше.

Kalen Delaney. Microsoft SQL Server 2012 Internals
Если первые 2 книги - руководства для начинающих, то вот этот монументальный труд не стыдно прочитать разработчику любого уровня. Самое подробное и всеобъемлющее руководство из тех, что я видел. Держу оригинал книги под рукой в качестве справочника. Стиль изложения объемный и многословный.
Кому чтение книги по каким-то причинам не подходит, могу посоветовать статью от той же Kalen Delaney, содержание в целом соответствует стилю, выдержанному в книге. Там же я узнал, что у Delaney не так давно вышла отдельная книга, посвященная блокировкам в SQL Server:
При этом книжка бесплатная и доступна для скачивания в электронном виде! Да это просто праздник какой-то! Книга так же информативна, как и ее "старшая сестра", держу экземпляр под рукой.

И конечно, не будем забывать про официальную документацию.
TechNet: Locking and Row Versioning
Еще я планировал добавить ворох ссылок на различные мануалы по concurrency с codeproject, хабра и подобных сайтов. Отказался от этой идеи после очередного прочтения  Microsoft SQL Server 2012 Internals. Еще раз всем рекомендую почитать и напоминаю, что я кое-как сравнил между собой только посвященные конкурентному доступу материалы в этих книгах - в районе 1 главы из каждого источника. Удачи!


пятница, 10 июля 2015 г.

AutoMapper: internal properties mapping

Ранние версии AutoMapper умели производить маппинг только публичных свойств классов. Ситуация изменилась в версии 3.3.0 - появилась долгожданная возможность мапить не только public, но и internal свойства путем указания перечисления BindingFlags:
Mapper.Initialize(cfg =>
{
   cfg.BindingFlags = 
      BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
});
К несчастью, эта фича вновь стала недоступна в версии 3.3.1. По словам автора - так как возникли проблемы с реализацией под все платформы. Есть вероятность, что BindingFlags вернутся в следующих версиях AutoMapper. Обсуждение на GitHub.

четверг, 9 июля 2015 г.

AutoMapper: хитрости

Вольный сокращенный перевод понравившегося поста с CodeProject. Рассматриваемые темы:

1. Projection
2. Configuration Validation
3. Custom Conversion
4. Value Resolvers
5. Null Substitution


В отличие от автора, я бы поставил Configuration Validation на первое место по важности. Проверка соответствия свойств класса-результата и класса-источника гарантирует, что любые опечатки, переименования и просто несоответствия имен не останутся незамеченными. Маппинг становится прозрачным и предсказуемым. Но обо всем по порядку: