如何使用 AutoMapper 的 ValueResolverAttribute

How to use AutoMapper's ValueResolverAttribute

我已经使用映射的属性方法(在AutoMapper 8.0中引入)对这一点进行了大量映射。 我更愿意继续使用属性方法。

但是,我不知道如何在以下情况下实现 ValueResolverAttribute,我尝试将字符串 ("ConfigurationSetting.Key") 映射到一个对象包含有关给定配置设置的更多信息 ("ConfigurationSettingDTO.Key"):

来源

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

    public string Value { get; set; }
}

目的地

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

    public string Value { get; set; }
}

自定义值解析器

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 documentation 没有 明确说明如何使用此属性。


编辑:为了更清楚,应用程序在 Startup.cs 中以下代码块的第一行崩溃:

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

您可以使用它的方法之一是使用配置文件 Class,我假设您正在 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; }
}

自定义值解析器

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);
    }
}

然后创建一个 class 实现配置文件,如下所示:

自定义配置文件CLASS

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

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

然后在您的 Startup.cs Class 中执行此操作。

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

这是在 ConfigureServices 方法中调用的最后一行。我希望这有帮助。

此致。

我发现我的属性不正确。

我需要使用 ValueConverter.

而不是 ValueResolver

目的地:

[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);
    }
}