Наконец-то стали появляться первые видеозаписи с прошедшего 16 марта семинара DevPRO.
На семинаре я выступал с докладом о разработке мобильных приложений с использованием c#.
Заметки о .net и React разработке
Наконец-то стали появляться первые видеозаписи с прошедшего 16 марта семинара DevPRO.
На семинаре я выступал с докладом о разработке мобильных приложений с использованием c#.
Как известно, в ASP.Net MVC4 одной из главных появившихся фишек стал WebAPI.
Вместе с обновлением Web Tools 2012.2, вышедшем, как ни странно, в 2013, Майкрософт добавил к WebAPI интересную функцию — генерацию страницы помощи (help-page) с описанием вашего API в человеко-читаемом виде, и даже с примерами в виде xml и json. Большой плюс этой страницы в том, что информацию и описание API можно брать прямо из xml-комментариев к методам API-контроллера
Сегодня, однако, я натолкнулся на досадную ошибку в работе этой самой страницы помощи:
для метода вида
/// <summary> /// description /// </summary> [HttpGet] public string Tst([FromUri] TstModel filter) { return null; }
Проблема, как оказалось, была в том, что TstModel я, как водится, объявил вложенным классом (nested class) в самом контроллере. Из-за этого help page слегка потерял голову и необходимой документации не увидел :)
Для интересующихся и/или столкнувшихся с той же самой проблемой, фикс прост:
XmlDocumentationProvider.GetTypeName
line 109: return type.FullName.Replace("+", "."); //was: return type.FullName line 101: string typeName = genericType.FullName.Replace("+", "."); //was: string typeName = genericType.FullName
Может, кто подскажет, куда можно послать по этому поводу bug-report? :)
Кроме как через nuget письмом автору Microsoft.AspNet.WebApi.HelpPage — других вариантов не найдено :)
Сделал перевод ответа Роба Эштона на заметку Роберта Мартина «О стартапе-ловушке».
После появления перевода оригинальной статьи дяди Боба не мог не ответить переводом зацепившего ответа :) Тема моя любимая — про тесты.
Не стесняйтесь плюсануть на хабре (http://habrahabr.ru/post/172039/), если понравится :)
I love this feature!
И это реально то, чего не хватает в VS/Resharper :)
Попробуем добавить xml-комментарий к свойству:
public UIViewController CurrentViewController {
Набираем традиционные «///» и получаем…
/// <summary> /// Gets the current view controller. /// </summary> public UIViewController CurrentViewController {
Ну, я даже не знаю, что добавить :) Правда, иногда всё-таки приходится дописывать еще пару фраз :)
P.S. Может, кто-нибудь знает, как это сделать в VS?
На выходных попробовал RavenDB на небольшой задаче обработки массива документов. Документов было не очень много — порядка 50К, их обработка — задача разовая, но её длительность получалась однозначно порядка 10 часов, плюс всё это отлично параллелилось.
Поэтому возникла мысль загнать все эти документы в БД, чтобы без проблем сохранять промежуточные результаты и не волноваться за exception’ы, безвозвратно прерывающие обработку 10-часового процесса в самом конце :)
Raven-Embedded видился неплохим кандидатом для такого использования, поскольку позволял не париться с маппингами, быстро «установить» БД, просто добавив nuget пакет, позволял динамически добавлять в документы новые структуры данных (результаты обработок) ну и по идее должен был быстро работать :)
Что же из всего этого получилось?
Continue reading
Работать в Mac OS X после стольких лет программирования в windows — это настоящий стресс :) Причина проста и банальна — очень многие сочетания клавиш, к которым мы привыкли работают по-другому, или вообще не работают :)
Собственно, основные проблемы идут от того, что Ctrl переехал на клавишу Win, а Home и End переходят в начало и конец файла (а не начало и конец строки, как в windows).
К счастью, Ctrl и Win меняются местами прямо в настройках МакОси (Системные настройки -> Клавиатура -> Клавиши модификации), а Home и End возвращаются к привычному PC-функционалу с помощью DoubleCommand или ему-подобных утилит.
Эти два небольших шага сэкономили мне множество нервов и позволили сосредоточиться на деле, а не перестройке собственных привычек :)
Прочие же привычные по VisualStudio сочетания можно перенастроить уже прямо в MonoDevelop.
И да простят меня апологеты Mac OS за такие издевательства над системой :)
P.S. Спасибо Брайану Ханкинсу за наводки
На выходных (где-то с месяц назад, когда я только взялся за этот пост) наконец-то дошли руки до публикации исходников своей «инфраструктурной» библиотеки. По правде говоря, я это собирался сделать достаточно давно, но насущной необходимости не было, да и сейчас наврядли кому-то понадобиться заточенная по большому счету под личные нужды одна из сотен тысяч других библиотек-собраний-всяких-мелочей, однако публикация исходников вместе со своими собственными nuget-пакетами таки может кому-нибудь пригодиться.
Continue reading
В рамках MccTomskCamp 18 июля проводил небольшой вводный семинар по NHibernate. Ссылки на видео, презентацию и исходные коды можно найти в конце поста, а можно и посмотреть прямо здесь:
P.S. Большое спасибо всем посетившим семинар за проявленное внимание к мероприятию :)/a
Долгое время одним из первых шагов после создания нового MVC-сайта у меня было редактирование .csproj и добавление магического элемента
<mvcbuildviews>true</mvcbuildviews>
Напомню, что этой директивой включается компиляция Razor-вьюшек, таким образом об ошибках в .cshtml файлах можно узнать не в рантайме (при открытии веб-странички), а во время компиляции проекта. Опция, безусловно, очень удобная, но очень сильно замедляющая процесс сборки. Так, при отключенной опции наш средних размеров MVC-проект собирается за 1 секунду, а со включенной — за 10 секунд (в проекте всего лишь чуть больше 100 cshtml файлов).
Такая немаленькая задержка очень серьезно сказывается на разработке — по сути при каждом билде можно легко успеть «переключиться» на браузер и пролистать пару страничек :)
Таким образом от MvcBuildViews очень захотелось отказаться, но при этом не потерять возможность обнаружения ошибок во вьюшках во время компиляции.
Проблему решил замечательный RazorGenerator от Дэвида Эббо. РазорГенератор интегрируется в качестве Custom Tool для Visual Studio и преобразует каждую вьюшку в соответствующий c#-код, который и компилируется в момент компиляции проекта и выдает ошибки абсолютно аналогичные MvcBuildViews. При этом время компиляции с RazorGenerator’ом составляет(в нашем случае) ту же 1 секунду, что и без него (с отключенным MvcBuildView). Итоговый выигрыш — в 10 раз (10 сек — компиляция + MvcBuildViews, 1 сек — компиляция + RazorGenerator).
Continue reading
В рамках ModelUnbinder, об основном сценарии использования которого я уже писал, была решена еще одна немаловажная проблема — работа со «сложными» моделями.
Рассмотрим пример: допустим, у нас на сайте есть форма поиска, и есть экшен, который показывает результаты:
public class SearchModel { public string SearchString { get; set; } public bool InLocalArea { get; set; } public int Page { get; set; } public int PerPage { get; set; } } public virtual ActionResult Search(SearchModel searchModel) { return Json(searchModel, JsonRequestBehavior.AllowGet); }
Допустим, мы хотим дать ссылку на результаты какого-то поиска и хотим воспользоваться для этого T4MVC. Попробуем так:
<a href="@Url.Action(MVC.Home.Search(new HomeController.SearchModel() { SearchString = "qweasd", }))">Предзабитый поиск1</a>
В результате у нас получится URL вроде: http://localhost:30729/Home/Search?searchModel=MvcApplication2.Controllers.HomeController.SearchModel. Это, конечно, не совсем то, что нужно :) Для решения проблемы воспользуемся ModelUnbinder’ом:
protected void Application_Start() { //blablabla ModelUnbinderHelpers.ModelUnbinders.Add(typeof(HomeController.SearchModel), new PropertiesUnbinder()); }
PropertiesUnbinder — это анбайндер, поставляемый в комплекте с T4MVC. Собственно, с его помощью в данном случае мы и получаем требуемый результат, ссылка теперь выглядит таким образом: http://localhost:30729/Home/Search?searchModel.SearchString=qweasd&searchModel.InLocalArea=False&searchModel.Page=0&searchModel.PerPage=0. Конечно, и этот URL можно чуть-чуть улучшить (например, не писать дефолтные значения value-type’ов), но по крайней мере эта ссылка вполне корректно работает, а в исходном коде нам пришлось поменять всего одну строчку — добавление анбайндера.
В реальной жизни в таких случаях я предпочитаю создавать пустой интерфейс IComplexModel, который реализуют все подобные модельки, и добавлять анбайндер уже только для этого интерфейса. Таким образом код выглядит как-то так:
public interface IComplexModel { } public class SearchModel : IComplexModel { public string SearchString { get; set; } /* ... */ } protected void Application_Start() { //blablabla ModelUnbinderHelpers.ModelUnbinders.Add(typeof(IComplexModel), new PropertiesUnbinder()); }
Вот и всё! Можно лишь добавить, что PropertiesUnbinder отлично работает и с массивами внутри модели, то есть модель вида:
public class SearchModel : IComplexModel { public int[] Numbers { get; set; } }
так же будет вполне адекватно преобразована в соответствующий URL.
Как обычно, тестовый проект с примером можно скачать и полюбопытствовать. Буду рад, если это кому-нибудь пригодиться.