我是否错误地使用了
IValueResolver
?
实际上在 context.Mapper.Map
调用之前应该有一些实例重用逻辑,我想做的是使用自定义 A
将 AModel
实例映射到 IValueResolver
实例并正确处理 circular reference
。
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);
}
}
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 将不知道如何自行解决它。重写映射器配置或将有问题的代码移出映射过程。