[英]Can't access automapper context items after upgrade to 9
我有一个这样的映射器:
CreateMap<Source, ICollection<Dest>>()
.ConvertUsing((src, dst, context) =>
{
return context.Mapper.Map<ICollection<Dest>>
(new SourceItem[] { src.Item1, src.Item2 ... }.Where(item => SomeFilter(item)),
opts => opts.Items["SomethingFromSource"] = src.Something);
});
CreateMap<SourceItem, Dest>()
.ForMember(d => d.Something, opts => opts.MapFrom((src, dst, dstItem, context)
=> (string)context.Items["SomethingFromSource"]));
这给了我一个例外,说You must use a Map overload that takes Action<IMappingOperationOptions>
。 好吧,我确实使用了执行此操作的Map
重载。 我还能怎么做?
这是因为这个变化:
https://github.com/AutoMapper/AutoMapper/pull/3150
您可以通过访问 ResolutionContext 的 Options 属性来获取项目。
将context.Items["SomethingFromSource"]
更改为context.Options.Items["SomethingFromSource"]
。
当没有 Items 时, ResolutionContext
与DefaultContext
相同。 因此ResolutionContext.Items
属性将引发异常。
但是,如果有, ResolutionContext.Items
将与DefaultContext
不同。 因此ResolutionContext.Items
将返回列表。
虽然ResolutionContext.Options.Items
将始终返回列表,但它不会抛出任何异常,无论它是否为空。 我相信这是错误消息的意思,因为ResolutionContext.Options
是一个IMappingOperationOptions
此扩展可以帮助迁移到 AutoMapper 12
public static class AutoMapperExtensions
{
public static TDestination MapOptions<TDestination>(this IMapper mapper, object source, Action<IMappingOperationOptions<object, TDestination>> OptionalOptions = null)
{
return mapper.Map(source, OptionalOptions ?? (_ => {}) );
}
}
在注入了 IMapper 的 Class 中
public class Command
{
protected readonly IMapper AutoMapper;
public Command(IMapper mapper)
{
AutoMapper = mapper;
}
private SomethingToDo()
{
var list = new List<string>();
// change for 12
var result = AutoMapper.MapOptions<IList<Item>>(list);
// prior to 12
//var result = AutoMapper.Map<IList<Item>>(list);
}
}
使用内部映射器时的几点考虑(即context.Mapper
)
首先,尽量不要使用context.Mapper.Map<TDestination>(...)
,而是使用context.Mapper.Map<TSource, TDestination>(...)
,它的表现要好得多。
其次,在内部映射器中使用上下文会破坏封装。 如果您需要在内部对象中设置值,请考虑以下两种解决方案:
如果您想在内部 map 之后设置值
context.Mapper.Map<Source, Dest> (source, opts => opts.AfterMap((s, d) =>
d.Something = source.Something))
如果您想在内部 map 之前设置值
context.Mapper.Map<Source, Dest> (source, new Dest()
{
Something = source.Something
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.