Saturday, October 26, 2013

Как откатиться к предыдущей версии nuget пакета

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

Вот небольшой снипет, автоматизирующий задачу.
Замените имя пакета и версию и вставьте его в Package Manager Console.

$packageName = Newtonsoft.Json;
$version = 4.0.5
$projects = Get-Project -all
$projectsWithPackage = new-object System.Collections.ArrayList;
ForEach ($proj in $projects) { Write-Host $project.ProjectName; $projWithPackage = Get-Package -Filter $packageName -ProjectName $proj.ProjectName; if($projWithPackage.Length -gt 0) { $projectsWithPackage.Add($proj.ProjectName) } }
ForEach ($proj in $projectsWithPackage) { Uninstall-Package $packageName -ProjectName $proj -Force}
ForEach ($proj in $projectsWithPackage) { Install-Package $packageName -Version $version -ProjectName $proj }


Так и не понял как разбить длинные команды на несколько строк. Почему-то консоль в студии не понимает многострочных команд и сивола `. Ваши советы пришлись бы кстати :)

Tuesday, August 20, 2013

Azure role restart at role configuration update

I had a little trouble understanding what happens when Azure role configuration changes. According to the blog post I red, which comes first in the google search, instances should be recycled one by update domain, but I didn't see it happen. It was totally misleading.

Apperently, recycling is not the default behavior. You can only reboot if you subscribe to RoleEnvironment.Changing event and set RoleEnvironmentChangingEventArgs Cancel property to true. If there is no event handling, role keeps running.

It looked like recycling was default, because the code, that subscribed to RoleEnvironment.Changing and cancelling the event, was included into the role code template before SDK 1.3 as per this blog post.

What is more, there were no mentions in MSDN that default behavior is role recycling.

Lesson learned: be careful with blog posts :)

Sunday, December 2, 2012

Собственный бекап в облаке или в леднике

Исследование

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

Воодушевлённый недавней конференцией TechEd и Windows Azure, полез считать сколько будет стоить разместить 150Gb моих драгоценных фоточег там. 
Получилось, что если хранить данные в одном регионе, то за 1Gb надо заплатить $0.93. $139.5 в месяц. Что-то много.

Смотрим Google Cloud Storage. Там $0.063 за Reduced  availability storage (читай архив), что уже не плохо, но при желании всё это скачать, придётся заплатить $0.12 per Gb + плата за реквесты. В итоге, хранение дёшево, но скачивание дорого, хоть и надо редко.

Ищем дальше.
Что есть у Amazon. Там есть S3 и Glacier. S3 предназначен также для частого доступа. На его базе можно сделать свой собственный Dropbox. Кажется, на его базе Dropbox и сделан :)
В S3 есть reduced redundancy storage за $0.093 и ... хмм Glacier storage за $0.01 per Gb. На этом стоит остановиться и посмотреть внимательнее.

Amazon Glacier

Действительно, первое, что бросается в глаза — это супер-низкая стоимость хранения. За 150Gb моих фоточег в год надо будет заплатить всего $18. Такая дешевизна, судя по отрывочной инфе, достигается за счёт специально организованного и произведённого хранилища, где диски крутятся медленно и отключаются от питания, если не задействованы. Эдакое сонное царство ну или вековой ледник. Во всём этом ледяном великолепии кроется одна большая засада — сложность и высокая стоимость извлечения данных.

Для того, чтобы рассчитать оптимальную (в идеале нулевую) стоимость скачивания, надо сломать мозг об их алгоритм рассчёта. Во-первых, надо заплатить за выкачиваемый объём по цене $0.120 per Gb или $18 за все 150Gb, что, в общем, не много, но это далеко не всё. Чтобы что-то скачать, надо отправить запрос на извлечение данных, который будет выполнятся от 3-х до 5 часов. Вот это извлечение может быть очень дорогим. Бесплатно в месяц можно извлечь 5% от среднемесячного объёма. Другими словами, чтобы скачать бесплатно всё, надо потратить 20 месяцев. Кхм... Ну хорошо, так и быть. Если приспичит скачать всё и сразу, придётся выложить порядка $270. Wow-wow-wow. Это главная засада. Если хочется всё скачать, то придётся запастись терпением. Скачивать всё, вероятно, придётся редко. Только в случае тотальной потери всех жёстких дисков, на которых записаны фоточки, а фоточки у меня записаны сразу на 2 диска.

Итак, представим, что мы хотим извлечь 0.5Gb данных. Запрос на их извлечение будет выполняться какое-то время, но для расчёта стоимости всегда берётся 4 часа. Вычисляем пиковую часовую нагрузку на извлечение так 0.5 / 4 = 0.125Gb per hour. Далее надо вычесть  из этого бесплатные месячные 5%, но в дневном потреблении. 150 * 0.05 = 7.5Gb per month / 30 days = 0.25Gb per day. Это число надо поделить на количество часов, в течение которых выполнялось извлечение за этот день. Будем считать, что мы отправляем пять запросов в день и длятся они 20 часов, то есть делим ещё на 20. 0.25 / 20 = 0.0125Gb или 12 мегабайт. Всё-таки этот сервис предназначен для больших компаний, а они хранят сотни терабайт.

Тем не менее, с учётом бесплатного объёма, часовая пиковая оплачиваемая нагрузка на извлечение равна 0.05Gb - 0.0125Gb = 0,0375Gb. Умножаем на стоимость извлечения гигабайта $0.01 и количество часов в месяце 720 и получаем счёт = $0.27. Если мы умудримся не вылезать за эту пиковую часовую нагрузку, то сможем скачать всё достаточно дёшево за 150Gb / 0.5Gb = 300 запросов на скачиваение. Если представить, что мы делаем 4 запроса в день, то получим 75 дней или 60 дней, если делаем 5. В итоге, чтобы всё скачать дёшево, нам потребуется 3 месяца.

Ещё немного об «особенностях».
- Если хочется скачать всё, то лучше размазывать это всё по целому количеству месяцев от начала до конца (в моём случае 3), поскольку если мы что-то долго качали один месяц и немного не уложились и скачали хотя бы что-то в другом, то заплатим как за два.
- Все незавершённые запросы на извлечение суммируются, то есть если мы шлём следующий запрос на извлечение, пока один не завершился, то рискуем нарваться на увеличенную пиковую нагрузку, поэтому отправляем следующий запрос только тогда, когда предыдущий завершился. Это и не даёт нам считать, что мы сможем отправлять 6 запросов по 4 часа в день. Запрос может исполняться долше.
- Надо не забыть заплатить $0.050 за каждую 1000 запросов на извлечение и загрузку.
- Надо заранее разбить все свои данные на архивы оптимального размера, потому что если мы загрузим все 150Gb одним архивом, у нас не получится так хитро его разбить. Придётся запрашивать все 150 и успеть скачать его за сутки. Поэтому надо ещё придумать механизм архивирования и разбивания файлов на архивы, а потом ещё и восстановления их из этих архивов. Кроме того, список этих архивов с их Id надо хранить где-то отдельно. Скажем, в спредшите Google docs :) чтобы было совсем всё в облаке.

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

Попробуем разобраться с их API в следующий раз.

UPD. У меня оказалось 150Gb фотографий вместо 30 :)
Ссылки:
Glacier Pricing http://aws.amazon.com/glacier/#pricing
Pricing FAQ http://aws.amazon.com/glacier/faqs/#How_much_data_can_I_retrieve_for_free
Pricing forum thread https://forums.aws.amazon.com/message.jspa?messageID=374065#374065

Friday, June 15, 2012

Тестирование сопряжения клиентского JavaScript кода и представления в MVC

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

<html>
    <header>
       <script type="text/javascript">
         var pageInitVars = { /* initial state and variable values */ }
       </script>
    </header>
    

Такое сопряжение я использую в своих приложениях. Передать некоторое состояние в JavaScript можно и другими способами, например, используя data-* атрибуты (http://api.jquery.com/data/) либо загружая только разметку в виде шаблонов, наполняя её данными с помощью ajax-запросов. http://knockoutjs.com/ — тоже очень классная штука.

Вы скажете: «Фу, буэ, ты мешаешь JS-код и разметку». Я отвечу, что нет, не мешаю, JS код лежит аккуратно в header. Не вижу особой разницы, где именно в разметке закодированы эти данные: в атрибутах html или вот так явно в специальном блоке. Преимущество данного подхода в том, что мы явно декларируем в одном месте, что наш клиентский код зависит от таких-то начальных значений. Эдакий Dependency Injection. Более того, можно автоматизировать тестирование того, что View (а именно View должна отвечать за создание эти блоков) наполняет объект pageInitVars значениями. Короче говоря, мы хотим защититься от Null Reference Exception в клиентском коде.

Можно создавать тест для каждого представления и перечислять в нём переменные для клиентского кода, который оно должно инициализировать, а можно  — держитесь крепче  — найти в клиентском коде, связанном с данным представлением, все обращения к pageInitVars и протестировать, что View эти значения передаёт через ViewModel. Мне кажется, что это довольно простая задача. Заниматься парсингом JavaScript кода не обязательно. Достаточно искать все вхождения pageInitVars, или другого объекта с более удачным названием, смотреть на то, что идёт после точки, например pageInitVars.nextPageUrl и проверять есть ли этот Url во ViewModel. А что вы думаете по этому поводу? Тестируете ли вы клиентский код таким образом?

Friday, May 25, 2012

История интеграции ASP.NET WebForms и MVC

В этом посте хочу рассказать об использовании ASP.NET MVC в уже работающем WebForms приложении. Прежде чем начать делать что-то подобное, надо ответить на вопрос «Зачем?».

Кончено, зачастую нами движет желание попробовать что-то новое в работе — испробовать какую-то новую блестящую технологию, которая в сто раз лучше старой. Это субъективный фактор, за который цепляются все остальные. Загоревшись подобной идеей, мы начинаем собирать факты «за» и стараемся не обращать внимание на «против». Хочу лишний раз предостеречь от необдуманных шагов и тем более от сценария «всё старое выкидываем и переписываем заново».

Объективно веб-формы имеют своё право на жизнь и обладают рядом преимуществ, например с ними очень быстро можно сделать веб-форму, но, скажем, реализация AJAX через UpdatePanel выглядит как надругательство над всем разумом. Поэтому первое, что было решено: постепенно менять все места, где используется AJAX на MVC и разрабатывать новый функционал тоже на MVC. Отлаженные веб-формы было решено не трогать, но подвергнуть рефакторингу.

Разработчики, использующие ASP.NET MVC стараются использовать лучшие практики программирования, и основная прелесть этой технологии как раз в том, что она подталкивает разработчика делать это изначально: разделять логику частей приложения, инвертировать управление, писать юнит-тесты. Всё это, конечно, можно делать и в веб-формах, однако, в  тех приложениях, что попадались мне на глаза ничего этого сделано не было, поэтому пришлось немало потрудиться, чтобы внедрить в них элементы MVC Framework: использовать роутинг, изолировать работу с сессией, контекстом, сервисами через их интерфейсы , а разрешать зависимости при помощи IoC контейнера ( в нашем случае использовался Unity).

Уже довольно много написано о том, как скрестить MVC и WebForms. Напишу о своём опыте: что же всё-таки было сделано, а главное — как.

Wednesday, March 23, 2011

Как изменить тип проекта VisualStudio для MVC3

У меня был проект asp.net web-forms, который я сконвертировал в MVC3 при помощи NuGet package Скотта Хансельмана.

Далее, чтобы вижуал-студия обросла необходимыми плюшками для удобной разработки на MVC3, надо поменять тип проекта. Сделать это можно, открыв .csproj файл в редакторе, и изменив ProjectTypeGuids следующим образом:
<ProjectTypeGuids>{E53F8FEA-EAE0-44A6-8774-FFD645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

Thursday, July 22, 2010

Кодогенератор для создания шаблона мета-модели

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

Предлагаемый метод не даёт на выходе 100% готовый к использованию код. Скорее, это помощник для генерации заготовки кода, которую далее всё равно придётся менять. Конечно, можно было бы написать плагин с UI для Visual Studio, но это заняло бы гораздо больше времени. :)

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

Friday, July 16, 2010

Аннотирование модели данных, настройка отображения модели в DynamicData и ASP.NET MVC2 Templated helpers

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

Tuesday, April 27, 2010

Создаём ASP.NET Dynamic Data MVC проект

Что ж, пришло время чего-нибудь накодить. Да, к сожалению, в случае с DynamicData для MVC не получится написать три строчки кода, сделать 10 кликов мышью, чтобы получить работающее приложение. Придётся кодить и, судя по всему, много.

1. Будем разрабатывать приложение для управления данными в многострадальной тестовой базе данных компании Northwind, схема которой легко гуглится по запросу «Northwind database» и качается с сайта Microsoft.

2. Создаём ASP.NET MVC2 веб-проект, без юнит-тестирования.

Sunday, April 25, 2010

ASP.NET Dynamic Data MVC Preview под лупой

В этом посте давайте разберёмся с тем, какая функциональность заложена в ASP.NET Dynamic Data MVC Preview. Это станет логическим продолжением того, что мы делали в предыдущем посте и станет заключительным этапом приготовления к хардкодингу.

Посмотрим на структуру проекта:


Saturday, April 24, 2010

Компилируем ASP.NET Dynamic Data MVC Preview для работы с MVC 2

Давайте сегодня скачаем и разберём превью Dynamic Data для MVC. Хотя этому превью уже скоро стукнет два года, мы попробуем им воспользоваться. К сожалению, эта библиотека работает только с MVC версии 1, но у нас же есть исходный код, поэтому мы, как настоящие индейцы, попробуем подружить этот код с MVC 2.

Thursday, January 21, 2010

Scaffolding, автогенерация форм и интерфейсов управления данными.

Чтобы было не очень скучно, я поставлю себе определённую задачу и буду решать её, применяя технологии ASP.NET MVC. Насмотревшись всяких демо-роликов, мы сможем быстро начать писать простенькие веб-приложеница, но этого мало. Мне нужно больше.

Я хочу сделать генератор форм и списков для управления данными. Буквально недавно узнал заморское слово скафолдинг (scaffolding) и начал его везде говорить. Ну вы поняли, что всё то, о чём я только что сказал называется скафолдингом. Согласитесь, что короче сказать «скафолдинг», чем произносить это длинное заклинание про автогенерацию форм и списков по формально описанной структуре данных, хотя обычным людям всё же понятнее :) На самом деле, скафолд-приложение — это некое быстро достижимое или генерируемое прото-приложение, которое в дальнейшем можно усложнять и кастомизировать.

Ладно, с терминами разобрались. Давайте смотреть как обстоят дела со скафолдингом.
Профессионалы ASP.NET знают, что для этого надо использовать Dynamc Data, который отлично работал со старым добрым ASP.NET, а теперь даже может работать вместе с MVC, что не может не радовать. Следующие посты я буду посвящать предварительной реализации Dynamic Data for ASP.NET MVC. Буду его ковырять и понимать как с его помощью что-то делать. Тема эта достаточно обширна и в один пост её будет трудно уместить. Начнём с формального описания задачи, в котором будет содержаться ключ к её решению.

Задача скафолдинга

Большинство веб-приложений работают с данными: позволяют их смотреть, добавлять и редактировать. Это так называемые CRUD (create, read, update, delete) приложения, создание которых мы бы хотели максимально автоматизировать. Что для этого потребуется? В первую очередь, нужна схема (структура) данных, по которой можно восстановить всевозможные связи между таблицами и их полями. С этой схемой необходимо уметь как-то работать. Удобнее всего работать с объектной моделью этих данных. Далее есть два пути: (1) воспользоваться стандартными правилами отображения типов данных полей таблицы на html-форму, либо (2) задать самостоятельно, желательно максимально гибко и просто, конкретные правила отображения этих типов на форму.

С первым вариантом всё просто. Вспомните любой визуальный клиент к базе данных, например, родимый phpMyAdmin. Да, он из другой оперы про презренный php, но он хорошо иллюстрирует подход. Если поле varchar, то управляет им простой input type="text", если дата, то стандартный календарик, если bool — чекбокс, внешний ключ — Select ну и так далее.

Со вторым вариантом несколько сложнее он нужен, когда простые элементы управления: инпуты, чекбоксы, селекты и календарики, нам уже не подходят, либо помимо них нужно что-то ещё. Например, мы хотим загружать картинки с помощью SWFUpload, использовать WYSIWYG-редактор для текста, изобретать невероятный контрол, который будет управлять одновременно несколькими множественными связями и т.д. Если вы скажете, что в этом случае надо делать всё управление руками, то окажетесь неправы только отчасти. Да, все мудрёные контролы в стандартный набор не включены, но их же можно один раз написать, а потом много раз использовать — профит!

Таким образом, нам нужно разобраться каким образом можно получить интерфейс для доступа к схеме базы данных, каким образом сконфигурировать отображение этой схемы на html-форму в виде контролов, а также как это потом всё показать в ASP.NET MVC приложении.

Tuesday, January 12, 2010

Интересный факт о protected internal и немного о контроллерах

Вчера стало интересно как устроен внутри класс Controller из ASP.NET MVC 2.0 RC. Этот класс иллюстрирует замечательный паттерн Command, согласно которому, внутри класса должна быть реализована функция выполнения. В нашем случае,  Controller реализует интерфейс IController и определяет метод Execute, внутри которого подыскивает один из своих методов, способных обработать пришедший запрос, то есть вызывает один из своих Action-методов, которые возвращают объект подтипа абстрактного типа ActionResult.

Интересно то, что обычно эти экшены не создают новый объект, например new ViewResult(), а вызывают метод родительского класса Controller, например return View() или return Json(). Так вот, в классе Controller эти методы определены как protected internal, например,

protected internal JsonResult Json(object data)

Прочитав про модификатор internal в MSDN я узнал, что он ограничивает использование метода внутри сборки, то есть вызов метода с модификатором internal  в другой сборке приведёт к ошибке. Как же тогда оно работает? Как мы в своих контроллерах спокойно вызываем эти методы и никаких ошибок не происходит? Оказалось, что вместе модификаторы protected и internal связываются логическим или, то есть запись с ними следует читать, как
protected [OR] internal,
поэтому выходит, что вне сборки этот метод экземпляра класса вызывать нельзя, но наследникам класса в другой сборке — можно :)

Получается, что определив protected internal метод мы можем:
— внутри сборки 
          вызывать его как из классов-наследников, так и у экземпляра класса
— вне сборки
          только у наследников

Такие дела.

Sunday, December 20, 2009

С чего начать изучать ASP.NET MVC

Как гласит древняя китайская мудрость: «Путь в тысячу вёрст начинается с одного шага». Сделаем первый шаг и начнём изучать ASP.NET MVC.

В компании Microsoft с недавних пор завелась целая армия евангелистов — людей, не только активно пиарящих технологии своей компании, но и неплохо в них разбирающихся. Это обычно компетентные профессионалы и знатоки своей области, поэтому будем доверять им и смотреть в рот, пока они говорят. Главный в России по веб-деву и ASP.NET MVC — Гайдар Магдануров — позитивнейший человек и всё такое. Бывал у него на тренинге и слушал выступление на phpconf 2009 (месте окончательного разочарования в PHP) от знакомства с ним остаются хорошие впечатления. Так вот, на сайте Интернет-университета информационных технологий есть видео-запись его базового тренинга про ASP.NET MVC, которую мы и будем смотреть.
Гайдар расскажет о паттерне MVC, создаст простое веб-приложение и прикрутит к нему несколько фич вроде AJAX, RSS и капчи.