Лучшие практики для интеграции AutoMapper с сервисами данных WCF и EF4
Мы раскрываем модель предметной области с помощью WCF Data Services. Модель происходит из EF4 и требует дополнительной работы, чтобы привести ее в требуемую форму для публикации через веб-сервис.
Я хотел бы справиться с этим вне EF4, чтобы сосредоточить внимание на модели EDMX, а не на ее использовании. Моя идея состоит в том, чтобы создать настроенную "ServiceModel", которая предназначена специально для веб-сервиса и содержит специфичные для сервиса проблемы.
Мой вопрос заключается в том, как лучше подключить автоматы в середине WCF Data Services. Я использую службы данных WCF с пользовательским (основанным на отражении) поставщиком для ServiceModels. Где я могу преобразовать запрос OData (для ServiceModels) в запрос EF4 (для DomainModels) и отобразить результаты обратно в ServiceModels?
2 ответа
Я использую Automapper в моих службах WCF для сопоставления сущностей базы данных с контрактами данных. Для каждого сервиса я создаю статический класс AutomapBootstrap с методом InitializeMap. Затем для каждого сервиса я украшаю сервис атрибутом AutomapServiceBehavior.
Я не знаю, будет ли это работать для вашего сценария, потому что WCF Data Services немного отличается от стандартных сервисов WCF SOAP и сервисов, использующих WCF WebBindings.
Тем не менее, стоит посмотреть.
Это служебное поведение
[CoverageExclude(Reason.Framework)]
public sealed class AutomapServiceBehavior : Attribute, IServiceBehavior
{
public AutomapServiceBehavior()
{
}
#region IServiceBehavior Members
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
AutomapBootstrap.InitializeMap();
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
}
public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
}
#endregion
}
Это мой маппер
public class AutomapBootstrap
{
public static void InitializeMap()
{
Mapper.CreateMap<CreateBookmarkRequest, TagsToSaveRequest>()
.ForMember(dest => dest.TagsToSave, opt => opt.MapFrom(src => src.BookmarkTags))
.ForMember(dest => dest.SystemObjectId, opt => opt.UseValue((int)SystemObjectType.Bookmark))
.ForMember(dest => dest.SystemObjectRecordId, opt => opt.Ignore());
}
}
вот как я подключаю свой сервис для автоматизации
[AutomapServiceBehavior]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Clouds : ICloudService
{
// service operation implementation details elided
}
Последнее замечание, мой сервис - это ванильный сервис WCF, использующий WebBinding и обслуживающий данные в стиле REST.
Если ваша модель предметной области не очень проста и очень поверхностна (в ней очень мало коллекций), я бы рекомендовал не проецировать объекты вашего домена для создания слоя службы (DTO).
Скорее, я бы проецировал ваши DTO непосредственно из вашего хранилища данных (БД). Невыполнение этого требования приведет ко многим проблемам с SELECT N+1 и в итоге будет более дорогостоящим в обслуживании, чем просто гидратация ваших DTO непосредственно из таблиц вашей базы данных.