Скринкаст о Test-Driven SharePoint Development
Опубликовано: Октябрь 27, 2009 Filed under: Uncategorized | Tags: DLR, IronPython, MbUnit, Sapphire, sharepoint, tdd, TypeMock Оставить комментарий →Записал скринкаст о том, как разрабатывал Sapphire REPL WebPart.
REPL WebPart для SharePoint
Опубликовано: Октябрь 24, 2009 Filed under: .net, C#, DLR, Python, sharepoint, tdd | Tags: DLR, IronPython, Isolator, sharepoint, TypeMock 1 Comment »Intro
Сегодня я расскажу о прототипе первого компонента под ярлычком Sapphire. Это REPL WebPart. Эта веб-часть предназначенная для производства оперативных изменений на серверной стороне SharePoint, так же для удаленного исполнения скриптов и тестирования некоторых кусков кода.
PreBody
Производство данной веб-части было инициированно в довольно таки частых потребностях исполнения серверного кода с достаточной оперативностью, в недоступности средств разработки под рукой.
Здесь есть небольшая презетнация, в которой я постарался отобразить принципы работы Repl WebPart:
В добавок к слайдам расскажу о том, что веб-часть представляет собой классический хостинг Dynamic Languages Runtime языков, пока из которых доступен только Python.
Body
Далее хотелось поговорить о том, как же всё это у меня получилось, итак проект включает в себе несколько основных модулей:
- Веб-часть и контролы представления
- Хостинг языков
Далее о них поподробнее
Language Hosting
В связи с тем, что языков, которые я захочу реализовать в данном проекте является неограниченное множество, то конечно же мне необходима абстрактная фабрика для их создания, которая будет скрывать иерархию всех доступных языков и инкапсулировать их под интерфейсом:
{
ILanguage Create(string name);
}
public interface ILanguage
{
string Name { get; }
object Execute(string input);
void SetVar(string name, object value);
object GetVar(string name);
}
Отлично, далее к нашему проекту присоединяются сборки, необходимые для имплементации скриптовых языков:
- IronPython.dll
- Microsoft.Dynamic.dll
- Microsoft.Scripting.Core.dll
- Microsoft.Scripting.ExtensionAttribute.dll
- Microsoft.Scripting.dll
Всё готово для того, чтобы реализовать Python, как среду для исполнения кода, отлично, приступим:
{
private readonly ScriptScope _scope;
public string Name
{
get { return «Python»; }
}
public PythonLanguage()
{
_scope = Python.CreateEngine().CreateScope();
}
public object Execute(string input)
{
ScriptSource source = _scope.Engine.CreateScriptSourceFromString(input);
return source.Execute(_scope);
}
}
Далее немного усложним задачу, в связи с тем, что нам будет необходимо реализовать контекст для работы с SharePoint, выглядеть это должно примерно так:
private void python_should_assume_sharepoint_variables()
{
SPWeb fakeWeb = Isolate.Fake.Instance<SPWeb>();
Isolate.WhenCalled(() => fakeWeb.Title).WillReturn(«I’m fake web»);
var python = _factory.Create(«Python»);
python.SetVar(«__x__», «123″);
python.SetVar(«__web__», fakeWeb);
python.Execute(«__x__ = __web__.Title»);
var x = (string)python.GetVar(«__x__»);
Assert.AreEqual(x, «I’m fake web»);
}
Для работы с объектами SharePoint в из IronPython, нам необходимо добавить несколько библиотек:
_scope.Engine.Runtime.LoadAssembly(typeof(Uri).Assembly);
_scope.Engine.Runtime.LoadAssembly(typeof(SPList).Assembly);
Это будет основой нашей работы с динамическими языками
WebPart + WebControls
Создадим проект с помощью SPVisualDev, добавим в него feature, внутри которой создадим веб-часть Repl WebPart, всё остальные действия стандартные, однако есть небольшой нюанс, нам нужен будет объект, с помощью которого можно будет выводить строковые значения после исполнения. Я решил создать для этих целей объект с классическим названием Console, его реализация предельна проста:
{
private readonly StringBuilder _messageBuilder = new StringBuilder();
public void Write(object message)
{
_messageBuilder.Append(message);
}
public void WriteLine(object message)
{
_messageBuilder.AppendLine(message.ToString());
}
public string Message
{
get
{
return _messageBuilder.ToString();
}
}
}
Мы будем передавать его в среду исполнения языков, а после исполнения кода опрашивать его свойство Message и выводить его содержимое в нашу веб-часть.
EndBody
Все исходники проекта доступны на github: http://github.com/butaji/Sapphire
Так же предварительную версию Sapphire.Environment (решение поставляется в WSP) можно слить на CodePlex: http://sapphire.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=34895
Кратко о Patterns & Practices: SharePoint Guidance
Опубликовано: Октябрь 19, 2009 Filed under: .net, patterns & practices, Sapphire, sharepoint | Tags: patterns & practices, Sapphire, sharepoint Оставить комментарий →Интро
В данной статье я хочу произвести обзор руководства под названием “SharePoint Guidance” от подразделения Microsoft patterns & practices. Данное руководство предназначено разработчикам/архитекторам SharePoint, в нём описаны основные принципы построения систем на данной платформе. Над руководством трудились выдающиеся представители разработки под SharePoint, а так же он упорно держится в списке самых активных проектов на CodePlex. Далее чуть подробнее.
Описание руководства
Руководство фактически состоит из нескольких аспектов:
- SharePoint Guidance Library – библиотека наиболее используемых и полезных функций, таких как управление конфигурацией, абстрагирование слоя данных, логирование событий и сервисная инфраструктура
- Документация, в которой подробно описаны все принципы построения приведенных примеров, а так же руководства по основным вопросам, возникающим в разработке на SharePoint.
- Contoso Partner Portal Reference Implementation – показательное приложение на MOSS некоей компании Contoso, являющее собой экстранет-портал, в приложении используются практики наиболее приближенные к промышленным решениям.
- Contoso Training Management Reference Implementation – простое приложение HR-отдела, демонстрирующее базовые принципы построения решений на WSS.
- QuickStarts – два небольших примера самых простых приложений на SharePoint, а так же доступа к данным
Помимо исходных кодов и юнит-тестов к ним, примерами так же являются установочные скрипты, билд-скрипты, что фактически является артифактами верно налаженного процесса производства ПО, что очень показательно и полезно с практической точки зрения.
Обзор руководства
1ая версия вышла в прошлом году (Dec2008), в настоящее время доступна 2ая версия данного руководства (Aug2009), о ней и будет идти речь.
- Introduction – небольшое введение, а так же рекомендации к инструментам разработки: VSeWSS, U2U CAML Query Builder, CAML.NET, Typemock Isolator
- Developing SharePoint Applications – основные сценарии разработки под платформу, а так же её ключевые возможности
- Design and Development Guidelines – отображены ключевые моменты архитектуры SharePoint, а так же описаны подходы решения тех или иных задач разработки под платформу; описаны рекомендации к управлению жизненным циклом проектов
- Application and Design Patterns – одна из наиболее интересных глав, в ней описаны как классические паттерны построения корпоративных приложений ложатся на решения под SharePoint
- The SharePoint Guidance Library – описание библиотеки со всеми ключевыми возможностями и компонентами для разработки
- Integrating Line-of-Business Systems – описание интеграции с существующими корпоративными системами
- Considerations for Content-Driven Applications – здесь можно узнать о том, как правильно строить приложения, для хранения контента
- Considerations for Enterprise-Scale Applications – рекомендации по созданию приложений масштаба предприятия
- Considerations for Extranet Development – рекомендации по разработке и планированию экстранет-порталов
- Partner Portal Reference Implementation – описание построения приложения-примера для MOSS
- Training Management Reference Implementation– описание построения приложения-примера для WSS
- QuickStarts – описание приложения для легкого старта работы с SharePoint
Критика
Данное руководство содержит в себе большое количество практичной полезной информации, однако в некоторых технических решениях моя точка зрения расходится с его создателями, в связи с чем мною был начат проект Sapphire: SharePoint Application Framework, который будет так же являться каркасом для построения решений на SharePoint, а так же включать примеры решений и необходимые в повседневной разработке компоненты.
Ресурсы по SharePoint Guidance
Скачать полную версию за август 2009 года можно здесь:
SharePoint Guidance так же представлен на CodePlex: http://www.codeplex.com/spg/ здесь можно задать интересующие вопросы и скачать все последние изменения.
Так же некоторые главы из SharePoint Guidance представлены в видеоряде на channel 9:
- Setting up the Contoso RI – p & p Developing SharePoint Applications guidance
- Walkthrough of the Contoso Reference Implementation- p & p Developing SharePoint Applications guidance
- How to use the configuration component? – p & p Developing SharePoint Applications guidance
- How to use the logging components? – p & p Developing SharePoint Applications guidance
- How to use the SharePoint Service Locator? – p & p Developing SharePoint Applications guidance
Ресурсы по SharePoint
TechNet располагает огромным количеством статей и книг по SharePoint, конечно в них не так много внимания уделено именно разработке, однако для формирования вижна платформы весьма полезно: http://technet.microsoft.com/en-us/library/cc262788.aspx
SharePoint Developer Center здесь можно найти практически всё, что нужно для разработки на SharePoint
Habrahabr, Live Writer и Code Highlighting
Опубликовано: Октябрь 17, 2009 Filed under: .net, Blog, Live, Python | Tags: IronPython, Live Writer, Pygments 1 Comment »Интро
Уже практически полгода я пользуюсь Windows Live Writer в качестве инструмента для написания веб-ориентированных статей. Это отличный инструмент, работающий с большим количеством blogengine’ов, и даже с SharePoint. Но разговор не об этом, в связи с тем, что я разработчик, мне частенько приходится вставлять листинг кода в написанные статьи, на это я и хочу обратить ваше внимание.
Пигменты
Многие представители Python-сообщества наверняка знакомы с дивным проектом под названием Pygments:
Ну так вот, товарищ Harry Pierson (@DevHawk) скомпилировал этот движок под IronPython и написал обертку-плагин для Windows Live Writer (качать здесь не торопиться). Отлично, однако то, что получается в результате его обработки не выделяется цветом на habrahabr, это связанно с некоторыми особенностями ресурса, однако поправимо.
Данными работами я и предлагаю заняться, для этого нам понадобятся:
- Исходники проекта (на GitHub’е)
- 5 мин времени
После того, как мы скачали исходники, стоит разыскать скрипт под именем pygments_package\devhawk_formatter.py и немного его подкоректировать:
# colors are readily specified in hex: ’RRGGBB’
if style['color']:
start += ‘<span style=»color:#%s«>’ % style['color']
end = ‘</span>’ + end
заменить на
# colors are readily specified in hex: ’RRGGBB’
if style['color']:
start += ‘<font color=»#%s«>’ % style['color']
end = ‘</font>’ + end
Далее пересобрать с помощью скрипта build.bat проект и запустить инсталлер – теперь то что делает данный проект в цвете отображается на хабре.
Вы подготовились к приходу AutoMapper?
Опубликовано: Октябрь 8, 2009 Filed under: .net, architecture, DDD | Tags: AutoMapper, DDD, DTO, POCO 3 Comments »Введение
Данная статья предназначена к прочтению разработчикам и архитекторам распределенных систем на платформе .NET. В ней будет рассмотрен гибкий каркас для объектно-объектного преобразования (далее маппинга). Так же будут рассмотрены некоторые аспекты Domain-Driven Design’а.
Зачем мне нужен объектно-объектный маппинг?
Следуя основным принципам DDD, мы реализуем так называемую Rich Domain Model (эти объекты также должны соответствовать принципу POxO). Объекты реального мира, нашедшие отражение в нашем приложении частенько так же передают достаточную сложность, следовательно, достаточно корректно построенная модель крайне тяжело поддаётся перемещению между слоями приложения (не путать с легкостью вносимых изменений).
Тем не менее достаточно часто появляется необходимость “распределения” (я имею ввиду создание промежуточных сущностей, а не растекание модели по слоям) модели между слоями, для отображения, к примеру, атрибутов её сущностей пользователям (в шаблонах представления MVx), а так же передаче по сервисам (Data Transfer Object). Порой бывает даже, что модель “распределяется” для тестирования некоторых аспектов.
Предположим, мы в Африке, у нас банановая плантация, всё классно, выращиваем, продаём, выращиваем, продаём, но тут внезапно внутренний рынок переполняется и нам надо расширятся (к примеру вести бананы в Россию), мы пишем WCF сервис, который будет слать наши бананы. Так как бананы в Африке имеют несколько иное значение, чем в России, то, соответственно нам понадобятся лишь некоторые атрибуты (остальные фактически не имеют значения), которые мы забубеним в наш DTO
Правильнее было бы дать классу BananaWrapper название BananaDTO, для того, чтобы точно отображать его функциональное назначение, но я оставлю название таким для большего уровня абстракции, к примеру, если нам понадобится сделать автомат по продажи бананов и поместить этот объект в Presenter Model
Хочу заметить, что порой задача преобразования объектов становится довольно-таки нетривиальной и в лучшем случаем выглядит примерно подобным образом (это решение в лоб, есть ещё более изощренные методы
):
- public class Banana
- {
- public string Country { get; set; }
- public double Price { get; set; }
- public int Age { get; set; }
- }
- public class BananaWrapper
- {
- public string Country { get; set; }
- public double Price { get; set; }
- public int Age { get; set; }
- }
- public class BananaMapper
- {
- public BananaWrapper GetWrapper(Banana banana)
- {
- return new BananaWrapper
- {
- Country = banana.Country,
- Price = banana.Price,
- Age = banana.Age
- };
- }
- }
* This source code was highlighted with Source Code Highlighter.
Думаю, что такой код писать, а тем более сопровождать, мало кому будет в радость, в последнее время я как раз частенько встречался с такого рода задачами, и находился в поиске решения проблемы.
AutoMapper
И тут на сцену выходит наш персонаж – AutoMapper, и сразу же говорит мне: – послушай, ты что такое пишешь? тебе не лень? ты не боишься допустить ошибок? хочешь я тебе помогу?!. Я конечно же соглашаюсь, и получаю в ответ следующее решение моей проблемы:
- public class BananaMapper
- {
- public BananaMapper()
- {
- Mapper.CreateMap<Banana, BananaWrapper>();
- }
- public BananaWrapper GetWrapper(Banana banana)
- {
- return Mapper.Map<Banana, BananaWrapper>(banana); ;
- }
- }
* This source code was highlighted with Source Code Highlighter.
Класс, и это действительно всё, что мне понадобится. Сложность, вышележащего примера снизилась в моих глазах до нуля.
Итак, что же за механизмы лежат внутри AutoMapper?
AutoMapper проверяет есть соответствующие поля в указанных типах, соответствие проводится как по имени свойства, так и по его типу. Даже такие нюансы, как Product.Name и ProductName будут учтены и обработаны автоматически (wow!). Плюс ко всему методы GetXXX() будут ложится на свойства XXX (да, ну и естественно для особо раздражительных все эти прелести можно отключить и переопределить всё в своих собственных таблицах соответствия (далее мапках)).
Кастомная конфигурация выглядит примерно следующим образом:
- Mapper.CreateMap<CalendarEvent, CalendarEventForm>()
- .ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.EventDate.Date))
- .ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.EventDate.Hour))
- .ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.EventDate.Minute));
* This source code was highlighted with Source Code Highlighter.
Кстати, все ваши кастомные конфигурации легко поддаются проверке с помощью следующего метода:
- Mapper.AssertConfigurationIsValid();
* This source code was highlighted with Source Code Highlighter.
Так же не плохо работает с:
- коллекциями
- вложенными мапами
- конверторами типов (к примеру string в int)
- нестандартной логикой инициализации
- форматированием
История
Проект появился в конце’08-начале’09, около полугода находился в версии 0.31, сейчас же добрался до RC 1.0, думаю, что релиз уже совсем скоро.
Overhead?
Дебаты по поводу того, насколько быстрее будет работать AutoMapper и присвоение свойств в ручную (и прочие мульки) я игнорирую, т.к. готов пойти на любые жертвы производительности, если получу ясный, читабельный код. Ах, да, автор AutoMapper позаботился об этих вопросах и написал бенчмарки, смотреть здесь: http://code.google.com/p/automapperhome/source/browse/#svn/trunk/src/Benchmark
Ресурсы
Скачать проект, а так же ознакомиться с исходными кодами можно здесь: http://code.google.com/p/automapperhome/
Обсуждения каркаса здесь: http://groups.google.com/group/automapper-users
Так же примеры использования есть здесь: http://automapper.codeplex.com/
Кстати проект разрабатывает Jimmy Bogard, который так же пишет BDD фреймворк для .NET под названием NBehave.


