Как использовать ValueResolverAttribute AutoMapper - PullRequest
0 голосов
/ 05 февраля 2020

Я использовал метод отображения атрибутов (введенный в AutoMapper 8.0), чтобы выполнить большое количество отображений к этой точке. Я бы предпочел продолжать использовать метод атрибута.

Однако я не знаю, как реализовать ValueResolverAttribute, учитывая следующий сценарий, в котором я пытаюсь отобразить строку (" ConfigurationSetting.Key") к объекту, который содержит дополнительную информацию о данном параметре конфигурации (" ConfigurationSettingDTO.Key"):

SOURCE

public class ConfigurationSetting
{
    public string Key { get; set; }

    public string Value { get; set; }
}

DESTINATION

[AutoMap(typeof(ConfigurationSetting))]
public class ConfigurationSettingDTO
{
    [SourceMember(nameof(ConfigurationSetting.Key)), ValueResolver(typeof(ConfigurationSettingKeyResolver))]
    public ConfigurationSettingKey Key { get; set; }

    public string Value { get; set; }
}

CUSTOM VALUE RESOLVER

public class ConfigurationSettingKeyResolver : IValueResolver<ConfigurationSetting, ConfigurationSettingDTO, ConfigurationSettingKey>
{
    public ConfigurationSettingKey Resolve(ConfigurationSetting source, ConfigurationSettingDTO destination, ConfigurationSettingKey key, ResolutionContext context)
    {
        return ConfigurationSettingKey.GetSettingKeyById(source.Key);
    }
}

При реализации вышеупомянутой попытки я получаю следующее исключение при запуске:

NullReferenceException: Object reference not set to an instance of an object.
AutoMapper.Execution.TypeMapPlanBuilder.BuildResolveCall(Expression destValueExpr, IMemberMap memberMap)

Документация AutoMapper явно не явно go объясняет, как использовать этот атрибут.


РЕДАКТИРОВАТЬ: Чтобы быть более ясным, приложение падает на первой строке в следующем блоке кода в Startup.cs:

var mapperConfig = new MapperConfiguration(cfg => cfg.AddMaps(AppDomain.CurrentDomain.GetAssemblies()));
IMapper mapper = mapperConfig.CreateMapper();
services.AddSingleton(mapper);

Ответы [ 2 ]

0 голосов
/ 06 февраля 2020

Я обнаружил, что мой атрибут неверен.

Вместо ValueResolver мне нужно было использовать ValueConverter .

НАЗНАЧЕНИЕ:

[AutoMap(typeof(ConfigurationSetting), ReverseMap = false)]
public class ConfigurationSettingDTO
{
    [ValueConverter(typeof(ConfigurationSettingConverter))]
    public ConfigurationSettingKey Key { get; set; }

    public string Value { get; set; }
}

ТАМОЖЕННЫЙ ПРЕОБРАЗОВАТЕЛЬ ЗНАЧЕНИЯ:

public class ConfigurationSettingConverter : IValueConverter<string, ConfigurationSettingKey>
{
    public ConfigurationSettingKey Convert(string source, ResolutionContext context)
    {
        return ConfigurationSettingKey.GetSettingKeyById(source);
    }
}
0 голосов
/ 06 февраля 2020

Один из способов, которым вы могли бы его использовать, это использовать класс профиля, я полагаю, вы работаете в ASP. NET Core.

Рассмотрите это:

ИСТОЧНИК:

public class ConfigurationSetting
{
    public string Key { get; set; }
    public string Value { get; set; }
}

НАЗНАЧЕНИЕ:

public class ConfigurationSettingDTO
{
    public ConfigurationSettingKey Key { get; set; }
    public string Value { get; set; }
}

ИНДИВИДУАЛЬНОЕ ЗНАЧЕНИЕ RESOLVER

public class ConfigurationSettingKeyResolver : IValueResolver<ConfigurationSetting, ConfigurationSettingDTO, ConfigurationSettingKey>
{
    public ConfigurationSettingKey Resolve(ConfigurationSetting source, ConfigurationSettingDTO destination, ConfigurationSettingKey key, ResolutionContext context)
    {
        // YOUR VALUE TO BE RETURNED HERE, YOU MIGHT WANT TO DOUBLE CHECK YOUR IMPLEMENTATION HERE
        return ConfigurationSettingKey.GetSettingKeyById(source.Key);
    }
}

Затем создайте класс, который реализует профиль следующим образом:

ПОЛЬЗОВАТЕЛЬСКИЙ ПРОФИЛЬ КЛАССА

public class YourCustomProfile : Profile
    {
          public GamingStandaloneProfile()
          {
               AllowNullCollections = true;
               AllowNullDestinationValues = true;

               CreateMap< ConfigurationSetting, ConfigurationSettingDTO>()
                    .ForMember(d => d.Key, opt => opt.MapFrom< ConfigurationSettingKeyResolver >());
          }
    }

Затем в вашем Startup.cs классе do this.

public void ConfigureServices(IServiceCollection services)
          {
               ....
               services.AddAutoMapper(typeof(Startup));
          }

Это последняя строка, вызываемая в методе ConfigureServices. Надеюсь, это поможет.

С уважением.

...