воскресенье, 20 марта 2011 г.

Сегодня Windows 7 довел меня до белого каления

На системном разделе моего ноутбука объем которого составляет 25 Гб (!) нехватает свободного места. Точнее там тупо ноль байт. Из-за этого масса проблем.

В качестве решения проблемы решил перенести c:\Program Files\ и c:\Program Files (x86)\ на другой раздел и сделать Junction Point.

Скопировал все содержимое, но теперь не могу удалить каталог и поменять права, даже с правами администратора.

Администратор не имеет права на удаление этого каталога, только TrustedInstaller и Local System имеет право удалить этот каталог.

Запустить cmd сессию от Local System аккаунта можно с помощью PsTools\PsExec. Но они не работают из-за какого-то дефекта в 64-редакции Windows 7.

Есть хотфик, который решает эту проблему, но чтобы его скачать нужно ввести свой email и капчу. Терпение на исходе.

На почтовый ящик пришло письмо с прямой ссылкой и паролем. Скачал, распаковал. После чего получил сообщение что hotfix не может быть установлен.



Если посмотреть на проблему изначально - 25 Гб под системный раздел для ноутбука это много или мало по состоянию на 2011 год?

Чтобы картина была более ясна отмечу что в каталог c:\Users я не сохраняю никаких своих документов.

Весь установленный софт занимает не так уж и много места:

305 Мб - C:\Program Files\
441 Мб - C:\Program Files (x86)\
1,31 Гб - C:\soft\ причем этот каталог можно не считать, так как все данные лежат на другом разделе, а это Junction Point.


Иногда я жалею что я .NET разработчик, который зависит от операционной системы Windows.

Если бы я в повседневной работе использовал только кроссплатформенные решения, то у меня хотя бы был выбор...


Update: Удалось найти достаточно простое решение моей проблемы вот тут
http://helpdeskgeek.com/windows-7/windows-7-how-to-delete-files-protected-by-trustedinstaller/

суббота, 5 февраля 2011 г.

The very first .NET Saturday in IT Café_

Сегодня, пятого февраля сходил на событие, проходящее под эгидой компании Ciklum, которое называется .NET Saturday.

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

Формат события такой. В обычном, но довольно привлекательном кафе освобождают часть зала, в зоне которого находится докладчик, все слушатели сидят прямо за своими столиками и слушают доклад. Один за другим идет ряд докладов с 15-ти минутными перерывами между ними. В перерыве между докладами можно попить чаю, кофе, поесть печеньки или конфеты.

Были прочитаны следующие доклады:
- Александр Краковецкий (Винница, head of MS User Group) «Тестирование производительности .NET приложений»;
- Дмитрий Пасько (Харьков, Team Leader) «NuGet- package management for the .NET platform»;
- Андерс Соренсен (Дания, Site manager) «Optimizing development in an offshore context»;
- Михаил Вальков (Харьков, Senior .net developer) «Antipatterns»

Мероприятие продолжалось с 15:00 по 19:00 и количество времени выделенного на каждый доклад было достаточным.

Признаюсь, что решение идти на это мероприятие меня в первую очередь натолкнула тема первого доклада, хотя после окончания мероприятия лично для меня оказались самыми интересными доклад Дмитрия Пасько по NuGet и доклад Андерса Соренсена.

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

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

Компания Ciklum планирует проводить подобные мероприятия около одного раза в месяц по субботам. Если вы вдруг узнаете о данном мероприятии, то рекомендую на него сходить хотя бы один раз для пробы.

На всякий случай отмечу, что я не работаю в Ciklum и не имею к компании никакого отношения даже не смотря на то, что по моей «вине» на это мероприятие пришло пять моих товарищей. :) Ребята, надеюсь что вам там тоже понравилось.

четверг, 2 сентября 2010 г.

Вышел Castle.Windsor (включая Core, DynamicProxy, DictionaryAdapter) версии 2.5

Ура товарищи.

Вышел стабильный релиз Castle.Windsor, который я со спокойной совестью теперь могу рекомендовать даже начинающим ЙОК-овцам (IoC, Inversion of Control).


В анонсе бета релиза была масса отличных новостей:
- объединили Castle.Core, Caste.DynamicProxy, Castle.DictionaryAdapter в Castle.Core
- объединили Castle.MicroKernel, Castle.Windsor в Castle.Windsor
- сделали ряд незначительных breaking changes (читал описание, там все очень экзотическое и редко используемое). Можно было бы более крепко пройтись по старому API
- весь устаревший API отметили как obsolete. До этого там была настоящая каша. Прямо как в Rhino.Mocks

Castle объединяет сборки, а (Microsoft) Unity декомпозирует. ...ребята которые пидалят Unity не ведают что творят :)


К счастью основная проблема с высоким порогом вхождения была решена - благодаря тому что методы были отмечены как obsolete, новички не будут выносить себе мозг в поисках того какие именно методы стоит использовать, а какие не стоит. Более того, разработчики обещают вообще удалить все obsolete методы в релизе 3.0.

До релиза 2.5, когда у меня спрашивали что лучше использовать в качестве IoC контейнера, я постоянно колебался в ответе. Обычно рекомендовал смотреть либо на Castle.Windsor либо на Autofac и говорил что если будут малейшие сложности с Castle.Windsor, то не морочить с ним долго голову.

Теперь же однозначно уверен что логичнее использовать Caslte.Windsor, а легкий Autofac стоит использовать только лишь в Silverlight проектах.


Пользуясь случаем приглашаю всех пользователей Caslte.Windsor "приложиться" к его улучшению, оставив свои предложения на фидбек сайте. Команда разработчиков реально прислушивается к пожеланиям их пользователей:

Provide more compact, discoverable fluent API


В качестве примера тут хорошо расписаны шаги миграции проекта S#arp Architecture на последнюю версию Castle.

Указывается как разрешить проблему зависимости NHibernate и Castle.Windsor на Castle.DynamicProxy, которая переехала в Castle.Core.

Описывается рефакторинг со старого API на новый API Castle.Windsor. Много внимания уделяется IWindsorInstaller, который мне очень понравился.



ЗЫ Да, я знаю что релиз как-бы вышел с пол месяца назад, но у меня таймауты... Уж простите :)

среда, 11 августа 2010 г.

Полиглотное программирование в .NET это хорошо. История внедрения IronPython

Неплохая статья. Выгодно отличается трезвым взглядом человека-практика.

Признаюсь что читать все комментарии сил не нашел, но хотелось бы оставить одну галочку в Success Stories исключительно для статистики. :)

Уже несколько лет работаю на одном большом проекте в котором с самого начала присутствовал скриптинг.

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

Но это было время .NET 1.1, IronPython'а тогда еще не было, а нам нужна была возможность написания скриптов, которые бы вызывались во время отработки различных фабричных методов.


В какой-то момент мы нашли проект IronPython и начиная с версии 1.0 RC я был человеком, который "двигал" этот язык и передавал опыт работы другим командам внутри нашего проекта.

Все это происходило медленно, но верно. По ходу дела я переезжал с одного релиза на другой, решая разного рода проблемы взаимодействия C# и IronPython при хостинге DLR внутри C# приложения.


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

Следующим этапом был постепенный перевод всех скриптов на более высокоуровневую объектную модель. Тут пришлось пройтись по некоторым не очевидным граблям, которые выплывали во время наследования абстрактных классов C# в типах, которые я реализовывал на языке Python.

В конечном счете теперь у нас на проекте появляется все больше и больше скриптов на IronPython, которые постепенно становятся все более "умными".

При этом, скажу что мы, как суровые челябинские разработчики, пишем без IntelliSense и без отладчика. Спасает то, что я разобрался как можно вытащить script stack trace. :)



В конечном счете я для себя сделал такой вывод:

Многоязыковость платформы .NET это однозначно хорошо, так как позволяет в определенных ситуациях находить отличные решения. И мне кажется что эта самая многоязыковость или даже "распыленность" Microsoft по C#/F#/VB.NET/IronPython/IronRuby вряд ли нанесет существенный вред платформе в целом и языку C# в частности.

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

суббота, 3 апреля 2010 г.

Inversion of Control and Dependency Injection. Ссылки

Inversion of Control and Dependency Injection: Working with Windsor Container
http://msdn.microsoft.com/en-us/library/aa973811.aspx

Ознакомительная статья, раскрывающая основные концепции Inversion of Control и Dependency Injection, которую написал Oren Eini aka Ayende Rahien. Носит предельно практических характер. Достаточно много хорошего материала, все изложение идет в ключе разработки некоего приложения (или сервиса) по обработке заказов. Крайне рекомендую эту статью к прочтению.


Inversion of Control and Dependency Injection with Castle Windsor Container. Four Parts.
Цикл статей об использовании Inversion of Control и Dependency Injection с помощью популярного фреймверка Castle.Windsor.
http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart1.aspx

Первая статья является вводной. Вначале статьи приводится пример кода в котором нарушается принцип разделения ответственности (Separation of concerns) и который написан без оглядки на Unit-тестирование. Затем приводится реализация кода с использованием принципа обращения зависимостей (Inversion of Control), а точнее с помощью Constuctor [Dependency] Injection. Вторая версия удобна с точки зрения тестирования, но не удобна в реальном использовании, так как клиент будет знать сразу о нескольких реальных типах. И заключительной части показывается использование IoC/DI контейнера, точнее его базовой части в виде Castle.MicroKernel API, а затем и в расширенной - Castle.Windsor.


http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart2.aspx

Во второй части рассматриваются инъекция опциональных зависимостей (Property Injection), приводится пример инъекции конкретной реализации (имеет смысл, когда на один и тот же интерфейс может быть несколько реализаций). В конце статьи приводятся примеры декларативного Xml конфигурирования основных коллекций - Array, IList, IDictionary.


http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart3.aspx

В третьей части показывается пример вынесения части конфигурации в отдельные разделы Xml конфигурации Castle.Windsor и включение этих параметров при декларировании сервисов. По простым примерам видно, насколько просто и одновременно мощно можно конфигурировать сервисы Castle.Windsor с помощью конфигурационного файла. Если нужно задать значение параметра, который имеет сложный пользовательский тип, то это можно сделать с помощью TypeConverter'а. Приводится, не совсем полезный пример реализации декоратора и его регистрации. Возможно это сделано для того чтобы потом можно было привести пример с define и if/else прямо внутри конфигурационного файла.
Всех описанных возможностей конфигруации хватит за глаза любому, даже самому энтерпрайзному приложению :)


http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart4.aspx

В четвертой части описывается крайне важный материал - управление жизненным циклом сервисов внутри Castle.Windsor контейнера.
Любому, кто собирается работать с Caslte.Windsor стоит обязательно разобраться в том, что такое Lifestyle, Lifecycle, Commision/Decomission и Release Policy. Чтобы не было неожиданно неприятных ситуаций как со мной и Web-приложением на production сервере :)
Информация по Facility довольно полезна, но не так критична.


Building the Policy Injection in 40 Minutes with Windsor
http://ayende.com/Blog/archive/2007/03/07/Building-the-Policy-Injection-in-40-Minutes-with-Windsor.aspx

Реализация Policy Injection в виде Facility для Castle.Windsor. Типичный пример аспект-ориентированного программирования. Не знаю кто придумал термин Policy Injection, и что конкретно он обозначает, но когда мне говорят реализация аспекта (AOP), то я сразу понимаю о чем идет речь.


Caching with Castle Windsor
http://consultingblogs.emc.com/owainwragg/archive/2008/10/31/caching-with-castle-windsor.aspx

Реализация Facility, которая обеспечивает кеширование данных используя аспект-ориентированный подход. Очевидно, что с помощью IoC и AOP-подхода можно достаточно удобно решать такие вещи как Security, Logging, Caching.


The joys of Castle.Services.Transaction
http://www.jroller.com/hammett/entry/the_joys_of_castle_services

Описывается использование AutomaticTransactionFacility. Просто апофеоз декларативной attribute-driven разработки. Выглядит настолько необычно что я даже не знаю, стоит ли пытаться повторить это дома :) В любом случае идея невероятно креативная.


Hidden jewels in the Castle stack: Transaction Services
http://blogs.taiga.nl/martijn/2008/12/03/hidden-jewels-in-the-castle-stack-transaction-services

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


List of .NET Dependency Injection Containers (IOC)
http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx

Достаточно обширная подборка IoC контейнеров на платформе .NET от Scott Hanselman'а.


BitterCoder's Wiki. Container Tutorials
http://wiki.bittercoder.com/Default.aspx?Page=ContainerTutorials&AspxAutoDetectCookieSupport=1

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

Внизу страницы приведена целая коллекция ссылок по рассматриваемой тематике на различные сторонние ресурсы.


Inject Some Life into Your Applications—Getting to Know the Unity Application Block
http://msdn.microsoft.com/en-us/library/cc816062.aspx

Вводная статья по Unity, IoC контейнеру, который разрабатывался силами Microsoft и затем был выпущен с открытым исходным кодом. Рассматриваются основные аспекты IoC контейнера. Все примеры кода приведены сразу на двух языках - C# и VB.NET.


IoC libraries compared
http://elegantcode.com/2009/01/07/ioc-libraries-compared/

Сравнение API у различных IoC контейнеров: Ninject, StructureMap, Unity, Spring.net, Castle.Windsor, Autofac. Следует принять во внимание что статья написана в январе 2009 года, а API каждого из перечисленный фреймверков постоянно совершенствуется.


Две простейшие реализации IoC контейнеров. По их реализации можно сделать вывод о том, какая основная задача ставится перед таким контейнером.

It's My Turn To Build An IoC Container In 15 Minutes and 33 Lines
http://www.kenegozi.com/Blog/2008/01/17/its-my-turn-to-build-an-ioc-container-in-15-minutes-and-33-lines.aspx

Building an IoC container in 15 lines of code
http://ayende.com/Blog/archive/2007/10/20/Building-an-IoC-container-in-15-lines-of-code.aspx

четверг, 11 марта 2010 г.

WatiN и ASP.NET integration tests

Не так давно пробовал библиотеку WatiN в работе, впечатления очень положительные.

На мой взгляд эту библиотеку очень выгодно отличает ее API. Он очень domain specific и его удобно использовать и читать.

Так же очень логично использовать так называемый "Page-based API", когда каждая страница в сценарии инкапсулирована в отдельный класс, унаследованный от класса WatiN.Core.Page. В этом классе описывается мэппинг контролов страницы на определенные свойста класса с помощью атрибутов, а так же реализуется логика взаимодействия со страницей в методах класса.

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

Классический API можно увидеть на главной странице сайта WatiN, я же приведу пример "Page-based API":
using (var ie = new IE("http://www.google.com"))
{
var page = ie.Page<GoogleSearchPage>();
page.SearchFor("WatiN");
}
...

[Page(UrlRegex="www.google.*")]
public class GoogleSearchPage : Page
{
[FindBy(Name="btnG")]
public Button SearchButton;

[FindBy(Name="q")]
public TextField SearchCriteria;

public void SearchFor(string searchCriteria)
{
this.SearchCriteria.TypeText(searchCriteria);
this.SearchButton.Click();
}
}

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

Пример реального кода на WatiN:
browser = new IE(fedExHomePageUrl);
browser.Page<FedExLoginPage>().LogIn(login, password);
browser.GoTo(fedExSearchPageUrl);
browser.Page<FedExSearchPage>().Search(dateFrom, dateTo);
browser.Page<FedExSearchResultPage>().SaveAs(reportPath);
browser.Page<FedExDownloadPage>().Download(browser, reportPath);
...

В коде выше описан верхний уровень сценария взаимодействия с сайтом FedEx. Глядя на код можно получить четкое представление о том, что нужно сделать пользователю для того чтобы скачать некий репорт с сайта. При этом все ньюансы разметки страницы и ввода данных сгруппированы и изолированы :)


WatiN даже умеет взаимодействовать со скрытым окном браузера, что позволяет запускать integration тесты на локальной машине прямо во время работы.


Стоит отметить, что в работе со скрытым окном браузера есть несколько ньюансов:

1. Если понадобится сделать скриншот страницы, то окно браузера необходимо сделать видимым, но не активным, иначе вместо скриншота у нас будет снимок черного экрана. Окно можно делать не активным, чтобы оно не мешало работе. После снятия скриншота окно можно будет сразу же спрятать:
browser.ShowWindow(NativeMethods.WindowShowStyle.ShowNormalNoActivate);
browser.CaptureWebPageToFile(debugImagePath);
browser.ShowWindow(NativeMethods.WindowShowStyle.Hide);

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

3. На моем копьютере WatiN отказывается работать в режиме Windows Service без доступа к рабочему столу, несмотря на то что на официальном сайте утверждается обратное.

...случайно заметил что в IE8 все вставки кода выглядят просто ужасно. Что интересно, FF и iPhone показывают правильно.

воскресенье, 31 января 2010 г.

Парсинг Html документов с целью извлечения данных

Ехал я как-то с работы вместе со своим коллегой Валерой Щербининым и заговорили о теме парсинга HTML.

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

Учитывая специфику проекта и интеграцию всего со всем я трижды сталкивался с задачей импорта данных из HTML документов в биллинговую систему.

Три раза я использовал один и тот же подход - Regular Expression.
Причем один из документов имел такую нетривиальную структуру, что мне пришлось использовать аж два регулярных выражения. В один проход я выделял все данные вместе с частью HTML разметки, а во второй уже выкусывал сами данные. Мне пришлось так поступить, потому как я уважаю мэйнтейнеров и не хочу писать код, после которого меня будут долго вспоминать.

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

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

Возможно Валера подумал что я полоумный, но тем не менее вежливо поделился своей идеей - использовать HTML Tidy для нормализации HTML до well formed XHTML, а потом наворачивать на это дело Xslt-преобразование которое извлекает все данные.

Идея мне сразу же понравилась. Но меня смутило то, что мне придется вызывать unmanaged HTML Tidy, плюс я практически незнаком с Xslt хотя и знаю XPath.

И вот, сегодня, совершенно случайно наткнулся на замечательное во всех отношениях решение - SGMLReader:
SGMLReader - Converting almost any HTML to valid XML

SGMLReader это pure C# .NET 2.0 библиотека, центральный класс которой это SgmlReader унаследованный от XmlReader со всем вытекающими отсюда преимуществами.

Есть даже примеры, которые запускаются на лету на живом коде из trunk:
HTML-to-XML Conversion Examples

Благодаря это библиотеке мне не придется погружаться в жестокий unmanaged мир и я смогу использовать Linq to Xml / Xslt / XPath на выбор.


В нагрузку ссылка на статью в которой описывается интеграция HTML Tidy и .NET. Если в двух словах то это либо P/Invoke либо COM Iterop. Брр...
Fix Up Your HTML with HTML Tidy and .NET


Ну и раз уж я удосужился написать пост, то упомяну что я завел себе твиттер :)
http://twitter.com/alexey_diyan

В твиттер я делаю посты очень часто. Всех интересующихся заверяю, что посты в твиттер буду делать только на техническую тематику.
Посты обычно касаются либо каких-то актуальных для меня вещей, изредка бывают 140-символьные размышлизмы.