Лучшие практики для интеграции AutoMapper с WCF Data Services и EF4 - PullRequest
13 голосов
/ 29 ноября 2010

Мы раскрываем модель предметной области с помощью WCF Data Services. Модель происходит из EF4 и требует дополнительной работы, чтобы привести ее в требуемую форму для публикации через веб-сервис.

Я бы хотел справиться с этим вне EF4, чтобы сосредоточить внимание на EDMX на модели, а не на ее использовании. Моя идея состоит в том, чтобы создать настроенную «ServiceModel», которая предназначена специально для веб-сервиса и содержит специфичные для сервиса проблемы.

Мой вопрос заключается в том, как лучше всего подключить автомаппер в середине WCF Data Services. Я использую службы данных WCF с пользовательским (основанным на отражении) поставщиком для ServiceModels. Где можно преобразовать запрос OData (для ServiceModels) в запрос EF4 (для DomainModels) и отобразить результаты обратно в ServiceModels?

Ответы [ 2 ]

22 голосов
/ 05 декабря 2010

Я использую Automapper в моих службах WCF для сопоставления сущностей базы данных с контрактами данных.Для каждого сервиса я создаю статический класс AutomapBootstrap с методом InitializeMap.Затем для каждой службы я украшаю службу атрибутом AutomapServiceBehavior.

Я не знаю, будет ли это работать для вашего сценария, поскольку службы данных WCF немного отличаются от стандартных служб 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.

0 голосов
/ 17 декабря 2010

Если ваша модель домена не очень простая и очень поверхностная (в ней очень мало коллекций), я бы не советовал проецировать объекты вашего домена для создания слоя ваших услуг (DTO).

Скорее я бы проецировал ваши DTO непосредственно из вашего хранилища данных (БД). Невыполнение этого требования приведет ко многим проблемам SELECT N + 1 и в итоге будет более дорогостоящим в обслуживании, чем просто гидратация ваших DTO непосредственно из таблиц вашей базы данных.

...