четверг, 27 ноября 2014 г.

DI vs. DIP vs. IoC

Существует три схожих понятия, связанных передачей и управлением зависимостями, в каждом из которых есть слово “инверсия” (inversion) или “зависимость” (dependency):

  • IoC – Inversion of Control (Инверсия управления)
  • DI – Dependency Injection (Внедрение зависимостей)
  • DIP – Dependency Inversion Principle (Принцип инверсии зависимостей)

Подливает масло в огонь рассогласованность использования этих терминов. Так, например, контейнеры иногда называют DI-контейнерами, а иногда IoC-контейнерами. Большинство разработчиков не различает DI и DIP, хотя за каждой из этих аббревиатур скрываются разные понятия.

среда, 12 ноября 2014 г.

Когда предусловия не являются предусловиями

UPDATE: библиотека Code Contract знает о тонкостях реализации таких возможностей как async/await и блоков итераторов. Поэтому описанные ранее проблемы касаются лишь старых (legacy) предусловий, основанных на if-throw. Если вы зашли сюда первый раз, то просто не обращайте внимания на этот абзац!

Что такое предусловие? Это некоторое утверждение, которое должно быть истинным во время вызова метода, причем за его истинность отвечает вызывающая сторона. Предусловия включают в себя проверку аргументов или внутреннего состояния объекта, а его нарушение проявляется в генерации вызываемым кодом исключений ArgumentException для невалидных аргументов, и InvalidOperationException для вызова метода в невалидном состоянии объекта.

Другими словами, предусловия гарантируют, что вызывающий код находится в нужном состоянии и ему передали все нужные данные для выполнения своей работы:

// class CustomStream
public Task<string> ReadString(int
position)
{
   
if (position < 0
)
       
throw new ArgumentOutOfRangeException("position"
);
   
if
(CanRead)
       
throw new InvalidOperationException("Stream is not readable"
);

   
return Task.FromResult("42");
}

среда, 5 ноября 2014 г.

О логировании исключений и Exception.ToString

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

Очень неприятно, когда тебе приходится разбираться с проблемой на боевом сервере в час ночи, когда все, что ты видишь в логе – загадочную строку “Exception has been thrown by the target of an invocation” или “The type initializer for ‘YourBestTypeInTheWorld’ threw an exception”. А все потому, что кто-то умудрился сохранять в лог не все исключение, а лишь его сообщение.

clip_image002