Показаны сообщения с ярлыком C#. Показать все сообщения
Показаны сообщения с ярлыком C#. Показать все сообщения

TDDigest e03

22 мая 2013 г. | | |

Для начала разберёмся, как писать тестируемый код на javascript, и поговорим о том, как тестировать полученный код с помощью QUnit, а так же как наслаждаться процессом тестирования асинхронного javascript с помощью Mocha #javascript #en #mocha
Туториал о том, как писать тестируемый и поддерживаемый код на php, чего избегать в коде, а что, наоборот, является правильным подходом. Ещё серия туториалов, детально раскрывающих процесс юнит-тестирования с PHPUnit. Рассматриваются такие темы, как написание полезного теста (!), моки, стабы, dependency injection, тестирование закрытых методов класса (если уж очень нужно), перегруженные конструкторы и почему 100% покрытие кода не так уж и важно. #en #php #phpunit

love via soap II: php + c#

27 февр. 2013 г. | | |

Часть 1, в которой рассказывалось, зачем это всё нужно, и как несложно реализуется взаимодействие  php-клиента с asmx-сервисом.
В этой части мы будем писать SOAP-сервис на php, а клиентскую часть - на C#.Так что пристегнись, это php!

Микромир ORM на примере Massive

12 февр. 2013 г. | | |

В мире больших и тяжеловесных ORM-решений, таких как NHibernate и Entity Framework, вполне предсказуемым стало появление течения микро-ORM: легковесных прослоек между БД и объектами приложения. Чем хороши microORM? Прежде всего, скоростью выполнения запросов: она сопоставима со скоростью чистых запросов через SqlDataReader. Потом - микро размерами: например, Massive - это всего лишь один подключаемый файл на 673 строки кода, в отличие от NHibernate или EF, которые тянут за собой целую dll-ку на несколько сот килобайт.  Наиболее известные из micro ORM:
1) Dapper, разработанный и активно использующийся в StackOverflow и StackExchange
2) Massive, разработанный Rob Conery, пример использования - HanselMinutes
3) PetaPOCO

Massive - это лучше, чем шоколад

Основа Massive - это dynamic-типы, появившиеся в .NET 4.0. Чтобы понять, что такое Massive, как и зачем он появился на свет, посмотриет видео  "Kill your ORM" с выступления Роба Конери на NDC 2011. А чтобы понять, насколько Massive лучше шоколада,  давайте напишем небольшое тестовое приложение, выводящее план счетов из БД в сгруппированом виде.

Через конструктор или через свойство?

10 сент. 2012 г. | | |

Инверсия управления (Inversion of control) - один из полезнейших приёмов при разработке в ОО стиле. Инверсия управления позволяет уменьшить связанность модулей приложения, за счет инъекций объектов-зависимостей в объекты-клиенты. Клиенты должны знать минимум о своих зависимостях - в пределах реализуемого интерфейса, если такой имеется - и совершенно ничего о процессе создания объектов-зависимостей. Существует несколько вариантов внедрения зависимостей. 
Под катом - перевод статьи Krzysztof Koźmi "To constructor or to property dependency?", в которой автор рассуждает, как лучше передавать объектам зависимости.
В [ ] находятся заметки переводчика.

Obsolete

15 авг. 2012 г. | | |

В одном небольшом, но сложном проекте, в неком простом, но важном классе жил-был обычный, но востребованный метод. Шло время, старые баги закрывались, добавлялись новые фичи, и настал день, когда метод устарел. Однако несколько классов, написанных другим разработчиком,  использовали его для своих тёмных делишек. “Разберусь с этим потом,” - подумал создатель метода, - “есть много дел поважне, чем эта ерунда,” Может быть, и закончилась бы эта история хэппи эндом, если б не ошибки в данных, которые начали материализовываться самым загадочным образом. Вот тогда-то и вспомнил хозяин метода про свой должок...

Загрузка файлов на сервер: php+C#

31 июл. 2012 г. | | |

Сценарий простой: клиент (winforms) хочет править миром загружать файлы на сервер (php). Первая мысль - использовать WebClient, у которого есть замечательный метод UploadFileAsync. На сервер вместе с файлом нужно передать пару-тройку дополнительных параметров, т.е. отправить стандартную форму типа:
<form action="http://localhost/uplad.php" enctype="multipart/form-data" method="POST">
<input type="text" name="title" value="" />
<input type="text" name="description" />
<input type="FILE" name="uploadfile" />
<input type="submit" name="send" value="Upload" />
</form>
И тут начинаются проблемы. Теоретически, это можно сделать, используя QueryString у WebClient:
If the QueryString property is not an empty string, it is appended to address. [MSDN]
Но практически тут нужен бубен:
Unfortunately, most file upload scenarios are HTML form based and may contain form fields in addition to the file data. This is where WebClient falls flat. After review of the source code for WebClient, it is obvious that there is no possibility of reusing it to perform a file upload including additional form fields.  [CodeProject]

Загадки старого кода

26 июл. 2012 г. | | |

Иногда очень занятно копаться в старом коде. Особенно в своём. Порой натыкаешься на гениально загадочные вещи, как-то:
if (level <= 5 && level > 4){ ... }
else
{
          if (level <= 6 && level > 5) { ... }
          else
                 if (level > 6) { ... }
 };
Давайте не будем обращать внимание на количество if-else операторов, на "магические числа"  и сфокусируем взгляд на проверяемых значениях в условных операторах. Этот феномен можно было бы попытаться  объяснить, если код был бы написан на языке с нестрогой типизацией, например, на том же php или javascript: в диапазон (4.0; 5.0] могло попасть множество значений (даже строка "4.098" т.к. в момент сравнения она будет автоматически преобразована в число с плавающей точкой - для php [1]). Но нет же!
C# является строго типизированным языком. Каждая переменная и константа имеет тип, как и каждое выражение, результатом вычисления которого является значение. Каждая сигнатура метода задает тип для каждого входного параметра и для возвращаемого значения.  [MSDN]
Остаётся мучиться в догадках, что за мистическая цифра могла бы находиться в целочисленном диапазоне (4; 5] кроме цифры 5. :)

[1] http://it2.php.net/manual/en/language.types.string.php см. раздел "String conversion to numbers":
When a string is evaluated in a numeric context, the resulting value and type are determined as follows.
If the string does not contain any of the characters '.', 'e', or 'E' and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float.

Love via soap I: asmx + php

14 февр. 2012 г. | | |

Задача очень простая: есть сервис на ASP.NET (asmx-сервис) и есть клиент на php, и нужно научить их общаться по http. Всё это просто реализуется через протокол SOAP.

Webbrowser. Сохраняем картинку.

16 нояб. 2011 г. | | |

Задача: сохранить из webbrowser генерируемую на лету (на основе данных post-запроса) картинку.
Решение:

Extensions, Static methods & null

23 окт. 2011 г. | | |

Методы расширения (extension methods), появившиеся ещё в C# 3.0,  - очень полезная штука.
Методы расширения позволяют "добавлять" методы в существующие типы без создания нового производного типа, перекомпиляции или иного изменения исходного типа. Методы расширения являются особым видом статического метода, но они вызываются, как если бы они были методами экземпляра в расширенном типе. (из MSDN)
Т.е. если в классе String нам не хватает какого-нибудь метода, то не нужно создавать еще один класс, наследуясь от String или, чего хуже, делая декоратор, а можно создать метод расширения:

public static class MyExtensions
{
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' }, 
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
 }   
(пример тоже из MSDN)
Иногда бывает ситуация, когда нужно вызвать метод расширения в статическом методе класса. Но этого нельзя сделать, несмотря на то, что
Методы расширения являются особым видом статического метода, но они вызываются, как если бы они были методами экземпляра в расширенном типе. (из MSDN)

Но, если всё же очень надо, то есть пара приёмчиков :)

Рефакторинг

20 окт. 2011 г. | | |

Сегодня наткнулась на такой вот метод:

Ещё чуть-чуть о тестах

18 окт. 2011 г. | | |

И еще одна небольшая заметка о TDD, точнее о том, что такое тест в контексте TDD.
Начинающие тэдэдэшники часто переусердствуют, стараясь тестировать всё и вся, забывая, что тест в TDD - это небольшой метод, проверяющий конкретное бизнес-правило. Акцент тут следует сделать на бизнес-правилах, они специфицируют поведение приложения, именно их нужно тестировать. С помощью TDD мы разрабатываем бизнес-логику. Не следует тестировать работу с БД, с файловой системой, сетевое взаимодействие - это уже совсем другой вид тестирования. Это интеграционные тесты. TDD позволяет нам быстро разрабатывать бизнес-логику, подтверждая работоспособность (или наоборот) кода мгновенным фидбеком. Если приходится специально что-то настраивать, чтобы запустить тест, и настройка занимает больше времени, чем написание самого теста, следует насторожиться. Метод для теста должен быть черным ящиком: известно только, что на входе, нужно удостовериться в правильности того, что на выходе.
В реальной жизни часто бывает так, что нужно взять выборку из БД и подсунуть данные методу для выполнения сложных расчетов. Для тестирования таких методов придумали Mocks, Fackes, Dummies & Stubs. Все эти технологии позволяют абстрагироваться от уровня физического взаимодействия, генерируя методы-заглушки. А методы заглушки возвращают тот набор данных, который им подсовываем. Чтобы было понятнее, вот простенький пример с Mock-библиотекой Moq.

to ORM or not to ORM?

16 окт. 2011 г. | | |

Плюсы и минусы ORM обсуждались не раз. Скорость vs удобство (отсутствие чистого SQL в коде), возможность тонкой настройки запросов для узких мест vs машинная генерация запросов (порой не оптимизированных)... Да и вобще, кому нужны эти лишние прослойки?
Почему стоит отказаться от ORM рассказывает Rob Conery в своём докладе "Kill Your ORM" на NDC 2011 , где, кстати, было очень много интересных докладов.


Linq DataContext и Dispose

7 окт. 2011 г. | | |

Как известно, любой DataContext объект является IDisposable. При использовании конструкции вида
using (CDataContext db = new CDataContext(ConnectionPool.Connection)) {...}
метод  Dispose() вызывается автоматически, и все занимаемые ресурсы освобождаются.
Насколько критично вызывать метод Dispose() вручную для такого кода?
CDataContext db = new CDataContext(ConnectionPool.Connection);
 return (from tbl in db._addresses
        where tbl.IsCustomer.Equals(true)
        select tbl).ToList();

Перефразируя вопрос: что плохого случится, если не вызвать  Dispose()? Ведь GC всё равно вызовет этот метод, разве что не сразу. DataContext не держит соединение c БД открытым (только, если не открывать его явным способом вроде DataContext.Connection.Open() ) т.е. никаких тяжеловесных ресурсов не занимает, и ничего плохого не происходит. Т.е. совсем не обязательно вручную вызывать Dispose().
Но. Если вы напишите такой код
using(CDataContext db = new CDataContext(ConnectionPool.Connection))
{
    return (from tbl in db._addresses
            where tbl.IsCustomer.Equals(true)
            select tbl);

}
произойдёт исключение "Cannot access a disposed object. Object name: 'DataContext accessed after Dispose.", потому что дерево запроса (возвращаемый тип  IQueryable<_address>) попытается выполнится после того, как DataContext будет уничтожен. Произойдёт это потому, что запрос выполнится тогда, когда будет впервые вызвано перечисление элементов (метод ToList<T>(), например). Если же написать такой код
CDataContext db = new CDataContext(ConnectionPool.Connection)
 return (from tbl in db._addresses
        where tbl.IsCustomer.Equals(true)
        select tbl);

то нужно понимать, что DataContext откроет соединение к базе, извлечет элементы и будет уничтожен только в том месте кода, где произойдет IQueryable<_address>.ToIEnumerable<_address>()

Moq: ошибка номер раз

29 сент. 2011 г. | | |

Дабы не получить ошибку "Invalid setup on a non-virtual (overridable in VB) member" при работе с библиотекой Moq, мокать нужно либо интерфейс класса:

var mock = new Mock<IEventsStorage>(); //этот подход является рекомендуемым

либо мокаемый метод нужно объявлять виртуальным:

var mock = new Mock<EventsStorage>();
mock.Setup(storage => storage.LoadEvents(Monthes.Januar)).Returns(new List<Event>());
 

...
 

public class EventsStorage
{
    public virtual List<Event> LoadEvents(Monthes monthNumber) {...}
}




Статические методы и методы экземпляра: кто быстрее

9 авг. 2011 г. | | |

Для некоторых методов класса Microsoft Code Analysis даёт такой совет:
CA1822 : Microsoft.Performance : The 'this' parameter (or 'Me' in Visual Basic) is never used. Mark the member as static (or Shared in Visual Basic) or use 'this'/'Me' in the method body or at least one property accessor, if appropriate. 
В MSDN по этому поводу написано:

«Members that do not access instance data or call instance methods can be marked as static (Shared in Visual Basic). After you mark the methods as static, the compiler will emit non-virtual call sites to these members. Emitting non-virtual call sites will prevent a check at runtime for each call that ensures that the current object pointer is non-null. This can result in a measurable performance gain for performance-sensitive code. In some cases, the failure to access the current object instance represents a correctness issue.»
Какие преимущества у static метода перед методом экземпляра? При каждом вызове метода экземпляра происходит проверка указателя на null. Для статических методов такого не делается, что даёт небольшой прирост производительности. Кроме того, согласно MSDN, для всех объектов класса будет существовать только один экземпляр метода, что так же увеличит производительность.

C# Finalize/Dispose pattern

13 июл. 2011 г. | | |

Два интересных обсуждения о Finalize/Dispose в C#  на StackOverflow (http://stackoverflow.com/questions/898828/c-finalize-dispose-pattern/898867#898867) и Хабре (http://habrahabr.ru/blogs/net/122639/)

VS 2010 Shortcuts Posters for C#, F#, VB, C++

26 окт. 2010 г. | | |

Появились новые постеры с горячими сочетаниями клавиш для разработки в Visual Studio 2010 под разные языки. Постеры выполнены в двух разных форматах - 8.5”x11”(Letter) и 210x297mm (А4)
Скачать с сайта Microsoft
Зеркало на C# for VS 2010 постеры
C# for VS 2008 

IoC, DI, WTF?

10 сент. 2010 г. | | |

Давайте разберемся с этими загадочными абревиатурами и разницей между ними.

IoC (Inversion of Control) -
инверсия управления, один из принципов S.O.L.I.D., известна так же как Принцип обращения зависимостей (Dependency Inversion Principle, DIP). IoC - очень полезная техника, которая уменьшает связанность и придает гибкость разрабатываемому ПО. Принцип инверсии управления звучит так [wikipedia]:

Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба типа модулей должны зависеть от абстракций. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
В своей статье Inversion of Control Containers and the Dependency Injection pattern Мартин Фаулер вводит понятие Dependency Injection (Dependency Injection) - внедрение зависимости - как разновидность IoC. Всего он выделяет три типа DI в зависимости от того, через что осуществляется DI:
1) Interface injection
2) Setter injection (пример)
3) Constructor injection (пример)

SqlCE 3.5 to 4.0 Converter

26 авг. 2010 г. | | |

Недавно (в июле этого года) вышла новая версия MS Sql CE, в которой был изменен алгоритм шифрования (стал использоваться SHA-2). Это означает, что для работы sql ce 4 с бд, созданной сервером версии 3.5, ее нужно предварительно переконвертировать. Для это в API предусмотрен специальный метод, поэтому особого труда конвертирование не вызовет.
Давайте напишем конвертер для файлов баз данных в формате slq ce 3.5 в формат slq ce 4.0.
Писать будем на C# в TDD-стиле, использовать VS 2008, тестировать в xUnit (последнюю версию можно скачать с codeplex). Когда вы используете TDD, не нарушая основных принципов ( а их всего три - RGR (красный-зеленый-синий): пишем тест, пишем код, рефакторим) и порядка их следования, то получаете автоматически приятные бонусы в коде.

Warning! Этот пост нужно рассматривать как пример по разработке в стиле TDD для начинающих.