guys.
Maybe someone has the same problem.
I have some cached variables in the MemoryCache
(standard non-distributed in-memory implementation of Microsoft.Extensions.Caching.Memory.IMemoryCache
). So, I also have mappings I use for Response/DTO creation. Some of them use variables from MemoryCache
. But now I must always pass it through
opts =>
{
opts.Items.Add(variableName1, variableValue1);
opts.Items.Add(variableName2, variableValue2);
...
}
or I need to pass each time MemoryCache
the same way.
Is it possible to set up a global configuration of ResolutionContext
which allows me to pass all variables from MemoryCache
I need in the time of the ResolutionContext
creation? Unfortunately, BeforeMap
isn't a solution - It has no DI mechanism for IMemoryCache
resolving. And as I know It can be only one in the mapping structure - Automapper skips all BeforeMap
after the first one.
Thank you.
Instead of using the ResolutionContext
, you can implement a custom IMemberValueResolver
, which can get the IMemoryCache
dependency injected.
By doing so, there's no need to seed theResolutionContext
with key/value pairs (being copied from the IMemoryCache
).
The FromMemoryCacheResolver
below resolves the value for the requested cache key from the injected 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);
}
}
Example
public class Source
{
public int Id { get; set; }
}
public class Target
{
public decimal DecimalValue { get; set; }
public string StringValue { get; set; }
}
Given the above Source
and Target
classes, you can define an AutoMapper
mapping that sets a target property to the value bound to a fixed cache key (see DecimalValue
rule) or a dynamic cache key (including a property value of the source object, see StringValue
rule).
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}"
));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With