为什么automapper在使用IValueResolver时会抛出stackoverflow异常?

问题描述 投票:0回答:1

我是否错误地使用了

IValueResolver
? 实际上在
context.Mapper.Map
调用之前应该有一些实例重用逻辑,我想做的是使用自定义
A
AModel
实例映射到
IValueResolver
实例并正确处理
circular reference

打开github问题

using AutoMapper;

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        B b = new B();

        a.B = b;
        b.List.Add(a);

        var mapper = new Mapper(new MapperConfiguration(cfg => { cfg.AddProfile<Profile1>(); }));

        var model = mapper.Map<AModel>(a);
    }
}

class A
{
    public B B { get; set; }
}

class B
{
    public List<A> List { get; set; }

    public B()
    {
        List = new List<A>();
    }
}

class AModel
{
    public BModel B { get; set; }
}

class BModel
{
    public List<AModel> List { get; set; }
}

class Profile1 : Profile
{
    public Profile1()
    {
        CreateMap<A, AModel>().ForMember(x => x.B, o => o.MapFrom<ValueResolver1>());
        CreateMap<B, BModel>();
    }
}

class ValueResolver1 : IValueResolver<A, AModel, BModel>
{
    public BModel Resolve(A source, AModel destination, BModel destMember, ResolutionContext context)
    {
        // some custom logic here
        return context.Mapper.Map<BModel>(source.B);
    }
}
c# .net wpf automapper stack-overflow
1个回答
0
投票

AutoMapper会自动处理循环引用,但是你的代码告诉AutoMapper无限地解析映射。如果您尝试在没有 AutoMapper 的情况下重写映射,您最终会得到如下结果:

private static AModel MapA(A a)
{
    return new AModel
    {
        B = MapB(a.B),
    };
}

private static BModel MapB(B b)
{
    return new BModel
    {
        List = b.List.Select(a => MapA(a)).ToList(),
    };
}

你能看到

MapA()
如何调用
MapB()
然后回调
MapA()
吗?这是一个循环,如果您的自定义创建了这种依赖关系,AutoMapper 将不知道如何自行解决它。重写映射器配置或将有问题的代码移出映射过程。

© www.soinside.com 2019 - 2024. All rights reserved.