升级到9后无法访问自动映射器上下文项

时间:2019-10-15 16:12:47

标签: c# automapper

我有一个像这样的映射器:

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重载来执行此操作。我还能怎么做?

2 个答案:

答案 0 :(得分:2)

这是由于此更改:
https://github.com/AutoMapper/AutoMapper/pull/3150

您可以通过访问ResolutionContext的Options属性来获取项目。

context.Items["SomethingFromSource"]更改为context.Options.Items["SomethingFromSource"]

没有项目时,ResolutionContextDefaultContext相同。因此,ResolutionContext.Items属性将引发异常。
但是,如果存在,ResolutionContext.Items将与DefaultContext不同。因此ResolutionContext.Items将返回列表。

尽管ResolutionContext.Options.Items将始终返回列表,但无论它是否为空,它都不会引发任何异常。我相信这就是错误消息的含义,因为ResolutionContext.OptionsIMappingOperationOptions

答案 1 :(得分:-1)

使用内部映射器(即context.Mapper)时需要考虑的几点

首先,尝试不要使用context.Mapper.Map<TDestination>(...),而应使用context.Mapper.Map<TSource, TDestination>(...),它的行为要好得多。

第二,在内部映射器中使用上下文会破坏封装。如果需要在内部对象中设置值,请考虑以下两种解决方案:

如果要在内部地图之后设置值

context.Mapper.Map<Source, Dest> (source, opts => opts.AfterMap((s, d) => 
    d.Something = source.Something))

如果要在内部地图之前设置值

context.Mapper.Map<Source, Dest> (source, new Dest()
    {
        Something = source.Something
    })