Отобразить строку в enum с помощью Automapper - PullRequest
8 голосов
/ 20 сентября 2010

Моя проблема заключается в гидратации Viewmodel из объекта Linq2Sql, который был возвращен из базы данных.Мы сделали это в нескольких областях, и для этого был разработан хороший многоуровневый шаблон, но последний элемент требует использования некоторых перечислений, и это вызвало головные боли повсюду.В настоящее время мы отходим от базы данных, затем используем Automapper для гидратации (или сглаживания) в наши Viewmodels, но наличие перечислений в модели, похоже, вызывает проблемы с Automapper.Я пытался создать собственные ресовлеры, которые удовлетворяли бы всем другим моим требованиям к отображению, но в этом случае это не сработало.

Пример кода выглядит следующим образом:

public class CustomerBillingTabView{
    public string PaymentMethod {get; set;}
    ...other details
}

public class BillingViewModel{
    public PaymentMethodType PaymentMethod {get; set;}
    ...other details
}

public enum PaymentMethodType {
    Invoice, DirectDebit, CreditCard, Other
}

public class PaymentMethodTypeResolver : ValueResolver<CustomerBillingTabView, PaymentMethodType>
{
    protected override PaymentMethodType ResolveCore(CustomerBillingTabView source)
    {

        if (string.IsNullOrWhiteSpace(source.PaymentMethod))
        {
            source.PaymentMethod = source.PaymentMethod.Replace(" ", "");
            return (PaymentMethodType)Enum.Parse(typeof(PaymentMethodType), source.PaymentMethod, true);
        }

        return PaymentMethodType.Other;
    }
}

        CreateMap<CustomerBillingTabView, CustomerBillingViewModel>()
        .ForMember(c => c.CollectionMethod, opt => opt.ResolveUsing<PaymentMethodTypeResolver>())

Я получаю следующую ошибку

[ArgumentException: Type provided must be an Enum.
Parameter name: enumType]
   System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult) +9626766
   System.Enum.Parse(Type enumType, String value, Boolean ignoreCase) +80
   AutoMapper.Mappers.EnumMapper.Map(ResolutionContext context, IMappingEngineRunner mapper) +231
   AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) +720

Я бы хотел использовать Automapper для всех наших картографических действий, но я видел, что многие люди говорят, что он не выполняет этот тип отображений, поэтому яя начинаю задаваться вопросом, использую ли я это неправильно?Кроме того, я видел несколько упоминаний ValueInjecter - это альтернатива Automapper, или будет полезно просто закрыть отверстия в Automapper для увлажнения моделей и использовать Automapper для выравнивания?

Да, я мог бы просто использовать строку в моей ViewModel, но я не фанат волшебных строк, и этот конкретный элемент используется помощниками для выполнения некоторой логики в ряде мест.

Ответы [ 2 ]

10 голосов
/ 20 сентября 2010

Это проблема с документацией AutoMapper. Если вы загрузите исходный код AutoMapper, там есть примеры. Код, который вы хотите, будет выглядеть так:

public class PaymentMethodTypeResolver : ValueResolver<CustomerBillingTabView, PaymentMethodType>
{
    protected override PaymentMethodType ResolveCore(CustomerBillingTabView source)
    {

        string paymentMethod = source.Context.SourceValue as string;

        if (string.IsNullOrWhiteSpace(paymentMethod))
        {
            paymentMethod  = paymentMethod.Replace(" ", "");
            return source.New((PaymentMethodType)Enum.Parse(typeof(PaymentMethodType), paymentMethod, true));
        }

        return source.New(PaymentMethodType.Other);
    }
}
5 голосов
/ 24 сентября 2010

вот решение с ValueInjecter : поскольку вы уже решили проблему, я просто укажу вам что-то похожее:

Строки AutoMapper для описания перечислений

в этом вопросе требования были немного больше, чем просто выполнение от строки к перечислению, но оно также включает это преобразование

о том, что ValueInjecter является альтернативой: да, это такнаберите больше общего, без конфигурации для каждой мелочи, и создайте любое соглашение, которое вы можете себе представить

...