Automapper 中的 ResolutionContext 创建自定义

Dmi*_*riy 4 c# automapper

伙计们。

也许有人有同样的问题。

MemoryCache我在(标准非分布式内存实现)中有一些缓存变量Microsoft.Extensions.Caching.Memory.IMemoryCache。因此,我还有用于创建 Response/DTO 的映射。其中一些使用来自 的变量MemoryCache。但现在我必须始终通过它

opts => 
{
   opts.Items.Add(variableName1, variableValue1);
   opts.Items.Add(variableName2, variableValue2);
   ... 
}
Run Code Online (Sandbox Code Playgroud)

或者我每次都需要以MemoryCache同样的方式通过。

是否可以设置一个全局配置,允许我在创建时ResolutionContext传递我需要的所有变量?不幸的是,这不是一个解决方案 - 它没有 DI 机制来解决。据我所知,它只能是映射结构中的一个 - Automapper 会跳过第一个之后的所有内容。MemoryCacheResolutionContextBeforeMapIMemoryCacheBeforeMap

谢谢。

pfx*_*pfx 6

ResolutionContext您可以实现一个自定义的,而不是使用IMemberValueResolver,它可以注入IMemoryCache依赖项。
通过这样做,无需使用ResolutionContext键/值对(从 复制IMemoryCache)作为种子。

下面FromMemoryCacheResolver从注入的 中解析请求的缓存键的值IMemoryCache

public class FromMemoryCacheResolver<TDestMember>
    : IMemberValueResolver<object, object, object, TDestMember>
{
    private readonly IMemoryCache _memoryCache;

    public FromMemoryCacheResolver(IMemoryCache memoryCache)
    {
        _memoryCache = memoryCache;
    }

    public TDestMember Resolve(
        object source, object destination, object cacheKey, TDestMember destMember,
        ResolutionContext context
        )
    {
        if (_memoryCache.TryGetValue(cacheKey, out object value)
            && (value != null)
            )
        {
            return (TDestMember)value;
        }

        return default(TDestMember);
    }
}
Run Code Online (Sandbox Code Playgroud)

例子

public class Source
{
    public int Id { get; set; }
}

public class Target
{
    public decimal DecimalValue { get; set; }

    public string StringValue { get; set; } 
}
Run Code Online (Sandbox Code Playgroud)

给定上述内容SourceTarget类,您可以定义一个AutoMapper映射,将目标属性设置为绑定到固定缓存键(请参阅DecimalValue规则)或动态缓存键(包括源对象的属性值,请参阅StringValue规则)的值。

CreateMap<Source, Target>()
    .ForMember(
        o => o.DecimalValue,
        opt => opt.MapFrom<FromMemoryCacheResolver<decimal>, object>(
            _ => "constant-cache-key"
    ))
    .ForMember(
        o => o.StringValue,
        opt => opt.MapFrom<FromMemoryCacheResolver<string>, object>(
            src => $"dynamic-cache-key-{src.Id}"
    ));
Run Code Online (Sandbox Code Playgroud)