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