Violet Tape некоторые мысли о разработке на платформе .Net

30Янв/120

Иерархичные структуры данных и промежуточные расчеты

Традиционной, в плане изучения программирования в школах, университетах, курсах повышения квалификации и так далее – является архитектура, в которой мы явно управляем ходом выполнения программы. Это начинается с фактически процедурного турбо паскаля и идеологически продолжается в «рабочих» для бизнес-программирования языках (С# и Java). Каждое действие программы задается явно, т.е. если надо что-то пересчитать после добавления нового элемента в коллекцию, то так и пишут: сервис Х пересчитай мне коллекцию с помощью метода Z. Это – push модель, мы толкаем/принуждаем систему сделать определенные действия.

Более интересной является pull модель, когда объекты сами говорят о том, что с ними следует сделать. При той же ситуации, что описана выше, надо только добавить объект в коллекцию, а дальше уже коллекция сама может сказать сервису Х пересчитать себя с помощью метода Z. Система реагирует на события внутри себя.

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

3Ноя/110

BLToolkit. Intro — II

Хранимые процедуры

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

Начнем с написания хранимой процедуры. Пусть нам требуется выборка людей старше определенного возраста.

create procedure Person_GetOlderThan(
		@Age int
)
as
set nocount on;

select PersonId
      ,Name
      ,Birth
      ,Resident
      ,Gender
      ,Weight
      ,Height
  from dbo.Person
 where datediff(yy,Birth, getdate()) > @Age
Метки записи: , , , Читать полностью
1Ноя/110

BLToolkit. Intro — I

Уже достаточно давно меня интересует тема CQRS, но пока что все останавливалось на изучении документов, примеров и самому написать что-то используя подход CQRS не доводилось. В последние дни работа в этом направлении активизировалась с новой силой, и пошлел процесс по исследованию инструментов более всего пригодных для реализации этой концепции. Наверно так повлияла конференция Patterns’n’Practices, когда было объявлено что к концу года команда выпустит гайдлайны по реализации CQRS на практике.

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

Насчет скорости работы есть диаграмма сравнения с другими фреймворками на 30 июля 2011 года:

Не могу не вспомнить фразу с презентации на NDC2011 по поводу Kill your ORM, где ведущий высказался в таком духе: «Linq2Sql вышел слишком простым и быстрым, поэтому придумали EF. Больше абстракций!».

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

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

Метки записи: , , , Читать полностью
16Июл/11Off

Ненавистный INotifyPropertyChanged

Да, уже из названия видно мое отношение к интерфейсу INotifyPropertyChanged и к его явной реализации в проекте. Я покрываюсь мурашками, и меня бросает в дрожь только при одном виде такого кода:

private string description;
public string Description {
    get { return description; }
    set {
        description = value;
        RaisePropertyChanged("Description");
    }
}

Какая растрата места на экране, какая колоссальная неэффективность написания кода, какая хрупкость в работе. Передача строковых переменных не может быть не хрупкой.

А когда таких свойств прописано с десяток и все это обернуто в регион (#region), то взгляд стекленеет, становится безжизненным и мозг отказывается верить в реальность происходящего. Конечно, самое большое зло от такого подхода – потеря времени на написание и на чтение.

Более того, это чистый инфраструктурный код, который не должен попадаться на глаза в логике приложения, только если специально его искать. Реализация INotifyPropertyChanged прямой и явный кандидат на реализацию в рамках аспектного-ориентированного программирования.

К сожалению, при разработке пользовательского интерфейса на WPF такая реализация «в лоб» встречается до сих пор сплошь и рядом. Не далее чем неделю назад вычищал такой код из рабочего проекта. Я бы порадовался за трудолюбие и усидчивость разработчиков пишущих такой код, но я склонен думать, что программист должен быть ленивым. В хорошем смысле. Так что лучше потерять немного времени на настройку и потом быстро-быстро все сделать. Далее я опишу 4 более-менее различных подхода к решению данной проблемы.

23Июн/110

Обновление WCF конфигурации online

Текущий проект на работе очень хорошо сконфигурирован и разнесен по слоям и уровням, проект имеет модульную структуру, построен на мелких и относительно автономных сервисах и все в нем хорошо! Кроме настройки портов для сервисов.

Сервисов сейчас больше 50 и каждый имеет свой отдельный адрес и порт. Количество сервисов постепенно растет, и я не удивлюсь, если через полгода их уже будет 100+. Естественно в таком подходе вопрос настройки сервиса и клиента встает в полный рост. Руками такое править сложно, да и не хочется. При таком количестве сервисов риск того, что порт будет уже занят, сильно отличен от нуля.

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

Дополнительного веселья добавляет тот факт, что сервисы могут запускаться от имени пользователя не входящего в группу Администраторов. Для этого надо будет резервировать для него пространство имен, в рамках которого пользователь сможет создавать WCF сервисы.

Наступает момент выпуска беты и время рвать волосы на голове, так как настройка приложения получается совсем не тривиальной, как для разработчиков, так и для пользователей. Чрезмерно сложные программы обновления файлов конфигураций, проблема доставки конфигураций до клиентов – куча никому не нужной мороки.

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

20Июн/110

Assert DSL

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

По науке, тесты являются документированием системы. Грамотно написанные тесты дают понять, как работает система, как ведет себя, причем читаться все это должно как готовая спецификация на поведение системы. Т.е. в идеале должен получаться связный и понятный текст. Это идеал, к которому постепенно приближаются методы тестирования, начиная от юнит тестирования и наиболее явно проявляясь в поведенческом/приемочном тестировании, когда сами тесты уже пишутся на языке бизнеса (в этом моменте вспоминаем Fitnesse).

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

В общем, все должно быть направлено на максимальную ясность и четкость тестов, чтобы явно было видно все взаимосвязи. Чтобы можно было восстановить логику программы по одним лишь тестам )) В дело читабельности пойдет не только Assert DSL, но и именование файлов, подход Arrange Act Assert. Все это не новые подходы как оказывается, но широкой известности пока не получившие, судя по тому, что я вижу в окружающих меня проектах. Да и сам я натолкнулся на новые темы случайно, изучая исходные коды StructureMap =)

Чтобы не томить, сразу расскажу какие основные шаги предлагаются для улучшения тестов:

  • Именовать тестовые файлы по основному методу, который тестируется
  • Использовать DSL  для создания объектов, чтобы методы делать максимально лаконичными
  • Стараться писать по методу «один метод – один assert»
  • Структурировать внутренности теста
  • Создать и использовать Assert DSL
29Май/110

MEF II

Продолжаем разговор о MEF и сегодня на повестке дня небольшие дополнения о экспорте/импорте, время жизни дополнений, способы создания дополнений, наследование дополнений.

Экспорт/импорт по контракту

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

С помощью контрактов, можно назначать дополнения на конкретные, заранее определенные поля, без привлечения фильтров и воборок в ручную.

Итак, пусть у нас есть все те же два дополнения. Теперь только мы объявим контракты к ним. Это делается очень просто:

[Export("RuContract", typeof(ILanguage))]
public class RuHello : ILanguage { ... }

[Export("EnContract", typeof(ILanguage))]
public class EnHello : ILanguage { ... }

После это в мастер-приложении надо будет только указать поля, помеченные как импорт определенных контрактов.  Конечно про композицию не стоит забывать тоже.

public class AddingComposer {
    [Import("RuContract")]
    public ILanguage Ru { get; set; }

   [Import("EnContract")]
   public ILanguage En { get; set; }

   public void Compose() {
      var catalog = new AggregateCatalog();
      catalog.Catalogs.Add(new DirectoryCatalog("Adding"));

      var container = new CompositionContainer(catalog);
      container.ComposeParts(this);
   }
}

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

 

Метки записи: , Читать полностью
15Май/110

Создание nuspec файлов автоматически

В новой версии NuGet 1.3 можно создавать nuspec файлы автоматически. Ну или в полуавтоматическом режиме. Для этого можно будет сделать внешнюю команду в студии и использовать ее при необходимости создания пакетов NuGet. Сейчас я покажу как это делается, и что получается в итоге.

Для начала надо заполнить данные об авторе и компании в настройках проекта. Это можно сделать либо в ручную отредактировав файл AssemblyInfo.cs

 

Либо в настройках проекта на первой вкладке можно перейти на окошко Assembly Info и там заполнить необходимые поля.

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

Файл спецификации nuspec создается с помощью команды spec. При этом рабочая директория должна быть та, где лежит файл проекта.

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

После того, как завершите настройку nuget, как инструмента создания nuspec файлов, можно использовать его. Выбираем проект, который будет оформлен в виде Nuget пакета, Tools > Generate NuSpec и получаем нужный нам файл.

Метки записи: Читать полностью
12Май/110

MEF

Сегодня я хочу рассказать о системе постороения динамического, модульного приложения с использованием Managed Extensibility Framework (MEF).  Вообще это уже достаточно старая технология, которая вылилась из системы Add-On от компании Микрософт. МEF стала дружелюбной оболочкой над монструозной системой предложенной ранее. Результат оказался настолько хорош, что MEF включили в поставку .Net Framework 4 по умолчанию, так что не потребуется искать и загружать библиотеки отдельно, беспокоится, есть ли данная библиотека у пользователя.

Так же уже понятно, что данную технологию можно использовать в Enterprise разработке, так как она в основной поставке фреймворка, а это такой аргумент, против которого менеджеры проектов не попрут. Обычно, менеджеры проектов очень неохотно идут на использование технологий и продуктов которые не упомянуты в пресс-релизах MS, даже если данная технология широко и успешно используется сообществом. Хотя их можно понять, это будет первый пункт, по которому их будут пинать в случае любых накладок.

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

 

MEF можно использовать начиная с версии .Net 3.5, взяв необходимые библиотеки с CodePlex. Как вы уже догадались, оттуда же можно взять исходный код и посмотреть как все это работает.

Основные возможности MEF:

  • Предоставляет стандартизированный способ для организации мастер-приложения и для дополнений к нему. В общем случае дополнения не привязаны к конкретному приложению и при реализации общего интерфейса могут быть использованы разными программами, что в целом не отменяет и жесткой привязки к мастер-приложения. Дополнения могут быть зависимы друг от друга и MEF самостоятельно подключит их в нужном порядке.
  • Предоставляет возможности поиска и загрузки дополнений силами самого MEF
  • Позволяет помечать дополнения метаданными, для дополнительных возможностей по подключению и фильтрации дополнений.
9Май/111

NuGet 1.3

Недавно вышла новая версия NuGet и я хотел бы освятить новые возможности, которые в нем появились. Сначала кратенько о том, что нового, потом подробнее рассмотрим изменения в привычных техниках работы.

Интеграция с symbol server

Теперь можно поставлять пакеты с файлами pdb для того, чтобы люди могли спокойно подебажиться в вашем проекте. Это может быть полезно, если вы разрабатываете общий продукт, а модули оформлены как nuget пакеты в локальном хранилище.

Новая команда Open-PackagePage

С помощью данной команды можно из командной строки менеджера пакетов переместиться на страницу пакета. Так же предоставляется возможность открыть и почитать лицензию, подать жалобу на пакет.

Общий синтаксис команды такой:

Open-PackagePage -Id <string> [-Version] [-Source] [-License] [-ReportAbuse] [-PassThru]

Последний параметр используется для того, чтобы получить URL страницы пакета в ответ, не открывая браузера.

Далее

 

Метки записи: Читать полностью