使用自定义值解析器映射时的解析器生命周期

Resolver lifetime when mapping with a custom value resolver

我正在使用 AutoMapper v9.0.0,我有源对象和目标对象,它们都包含一对多 parent/child 关系。

调用地图时,将处理一系列 ~100k SrcParent 个对象,其中 < 100 SrcChild 个对象。每个父映射都是单独调用的,因此 DstParent 对象的现有实例可以用 DstParent.ConfigurationId 值作为种子,MyValueResolver 值解析器只能执行 SrcChildDstChild 使用此数据进行转换。

映射器被添加到 asp.net 核心 di 容器,生命周期被 services.AddAutoMapper(assemblies, ServiceLifetime.Singleton); 覆盖。

但是,无论指定的生命周期如何,映射配置都会为每个子实例实例化一个新的解析器。存在哪些其他选项可以有效地转换父集合,其中子序列中的每个子实例都需要一个仅在运行时在目标父上可用的提示?

public class SrcParent
{
    public int Id { get; set; }
    public List<SrcChild> SrcChildren { get; set; }
}

public class SrcChild
{
    public int Id { get; set; }
    public int SrcParentId { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

public class DstParent
{
    public int Id { get; set; }
    public int ConfigurationId { get; set; }
    public List<DstChild> DstChildren { get; set; }
}

public class DstChild
{
    public int Id { get; set; }
    public int DstParentId { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

this.CreateMap<SrcParent, DstParent>()
    .ForMember(dst => dst.Id, opt => opt.Ignore())
    .ForMember(dst => dst.ConfigurationId, opt => opt.Ignore())
    .ForMember(dst => dst.DstChildren, opt => opt.MapFrom<MyValueResolver>());

public class MyValueResolver : IValueResolver<SrcParent, DstParent, List<DstChild>>
{
    public List<DstChild> Resolve(SrcParent source, DstParent destination, List<DstChild> destMember, ResolutionContext context)
    {
        /*
         * Many expensive operations that can be safely cached
         * on the resolver instance through the lifetime.
         */
    }
}

// Seed the mapper with an existing instance to hint the child conversion.
var dst = new DstParent
{
    ConfigurationId = 42
};

this.mapper.Map(src, dst);

有一个 MapFrom 重载,它将单例解析器实例作为参数。 也许更简洁的方法是简单地在单例服务中提取该逻辑并将其注入瞬态解析器服务。