Недавно начали писать приложение с использованием WCF Data Services. Сервисы получаются простыми, лёгкими, быстрыми - то что нужно для скоростного написания прототипа.
Недостатки, конечно, присутствуют. Вот что помешало работе в первый же день:
Дело в том, что в клиентских сущностях для коллекций используется класс DataServiceCollection<T> : ObservableCollection<T>. Решение мотивируется тем, что это позволяет напрямую биндить коллекции сущностей в UI. Однако класс ObservableCollection<T> не является thread-safe.
Что происходит: при материализации объектов, связанных с уже загруженными объектами, DataServiceContext вызывает метод InsertItem, который кидает InvalidOperationException.
Пришлось не побояться и попробовать T4 темплейты.
Столкнулся сразу с несколькими особенностями темплейтов:
P.S. Столько удовольствия приносят эти "развлечения", когда на день-два приходится отвлечься от "экстенсивного" кодинга (генерации контента) к "интенсивному" почти-программированию (исследованию технологий).
Недостатки, конечно, присутствуют. Вот что помешало работе в первый же день:
- Синхронная ленивая загрузка данных.
- Клиентские классы без возможности кастомизации.
- Функционал контекста конечно далёк от EF и RIA Services.
- Не прокидываются DataAnnotations, про которые знает EF.
Дело в том, что в клиентских сущностях для коллекций используется класс DataServiceCollection<T> : ObservableCollection<T>. Решение мотивируется тем, что это позволяет напрямую биндить коллекции сущностей в UI. Однако класс ObservableCollection<T> не является thread-safe.
Что происходит: при материализации объектов, связанных с уже загруженными объектами, DataServiceContext вызывает метод InsertItem, который кидает InvalidOperationException.
Пришлось не побояться и попробовать T4 темплейты.
Столкнулся сразу с несколькими особенностями темплейтов:
- Не подцепляется пространство имён. Логично, правда? Решается дописыванием строчки TransformContext.Namespace = "MyProject.Client.MyService";
- Версия протокола определяется как V1, из-за чего компилятор тут же начинает ругаться на методы Any. Поскольку сервисы у нас свои и в том же солюшне, закомментарил строчку //version = dataServiceVersion.Major.ToString();
- Не тащатся DefaultValue из edmx. Вот тут пришлось повозиться. Инструкция:
- В метод WriteTypeProperties для primitive types добавить:
var structuralType = property as IEdmStructuralProperty;
string defaultValue = string.Empty;
if (structuralType != null && structuralType.DefaultValueString != null)
defaultValue = structuralType.DefaultValueString.ToString(); - Этот самый defaultValue передавать в WriteTypeProperty и оттуда в WriteTypePropertyFields.
- В самом WriteTypePropertyFields убрать слово new и добавить его в другие WriteTypeProperty методы.
- Добавить обработчик строкового значения:
if (!string.IsNullOrEmpty(defaultValue)
&& primitiveType.PrimitiveKind == EdmPrimitiveTypeKind.String)
{
defaultValue = "\"" + defaultValue + "\"";
} - В методе WriteTypeStaticCreateMethod не обрабатывать свойства, у которых есть defaultValue:
var structuralType = property as IEdmStructuralProperty;
if (structuralType == null || structuralType.DefaultValueString == null)
nonNullableProps.Add(property);
- В метод WriteTypeProperties для primitive types добавить:
P.S. Столько удовольствия приносят эти "развлечения", когда на день-два приходится отвлечься от "экстенсивного" кодинга (генерации контента) к "интенсивному" почти-программированию (исследованию технологий).
Комментариев нет:
Отправить комментарий