C# 使用自定义值解析程序映射时的解析程序生存期
我使用的是C# 使用自定义值解析程序映射时的解析程序生存期,c#,asp.net-core,automapper,C#,Asp.net Core,Automapper,我使用的是AutoMapperv9.0.0,我的源对象和目标对象都包含一对多父/子关系 调用映射时,将处理~100kSrcParent对象序列和dst.Id,opt=>opt.Ignore()) .FormMember(dst=>dst.ConfigurationId,opt=>opt.Ignore()) .ForMember(dst=>dst.DstChildren,opt=>opt.MapFrom()); 公共类MyValueResolver:IValueResolver { 公共列表解析(
AutoMapper
v9.0.0,我的源对象和目标对象都包含一对多父/子关系
调用映射时,将处理~100kSrcParent
对象序列和<100SrcChild
对象。每个父映射都被单独调用,因此DstParent
对象的现有实例可以使用DstParent.ConfigurationId
值作为种子。在MyValueResolver
值解析器中,只能使用此数据执行SrcChild
到DstChild
的转换
映射器被添加到asp.net core 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);
public类SrcParent
{
公共int Id{get;set;}
公共列表{get;set;}
}
公共类子类
{
公共int Id{get;set;}
public int SrcParentId{get;set;}
公共字符串名称{get;set;}
公共字符串值{get;set;}
}
公共类父类
{
公共int Id{get;set;}
公共int配置ID{get;set;}
公共列表{get;set;}
}
公营儿童
{
公共int Id{get;set;}
public int DstParentId{get;set;}
公共字符串名称{get;set;}
公共字符串值{get;set;}
}
这个
.FormMember(dst=>dst.Id,opt=>opt.Ignore())
.FormMember(dst=>dst.ConfigurationId,opt=>opt.Ignore())
.ForMember(dst=>dst.DstChildren,opt=>opt.MapFrom());
公共类MyValueResolver:IValueResolver
{
公共列表解析(SrcParent源、DstParent目标、List destMember、ResolutionContext上下文)
{
/*
*许多可以安全缓存的昂贵操作
*在冲突解决程序实例的整个生存期内。
*/
}
}
//使用现有实例为映射器设定种子,以提示子转换。
var dst=新的dst父级
{
配置ID=42
};
this.mapper.Map(src,dst);
有一个MapFrom重载,它将单例解析器实例作为参数。
也许更简洁的方法是在单例服务中提取该逻辑并将其注入瞬态解析器服务。有一个MapFrom重载,它将单例解析器实例作为参数。
也许更简洁的方法是在单例服务中提取该逻辑并将其注入瞬态解析器服务。有一个MapFrom重载,它将单例解析器实例作为参数。但是如果在映射调用期间需要缓存内容,则需要context.Items。我现在看到opt.MapFrom(new MyValueResolver())
将实例的作用域设置为单个实例。缺点是我从服务提供商那里得到了松散的ctor注入,但是我可以从上下文的提供商那里得到。请添加一个供我选择的快速答案。也许更简洁的方法是在单例服务中提取该逻辑并将其注入瞬态解析器服务。这是一个好主意,由于无法跨配置文件共享实例,我已经遇到了不希望的副作用。感谢您的跟进。有一个MapFrom重载,它将单例解析程序实例作为参数。但是,如果您需要在映射调用期间缓存内容,则需要context.Items。现在我看到,opt.MapFrom(new MyValueResolver())
将实例作为单例进行作用域设置。缺点是我从服务提供商那里得到了松散的ctor注入,但是我可以从上下文的提供商那里得到。请添加一个供我选择的快速答案。也许更简洁的方法是在单例服务中提取该逻辑并将其注入瞬态解析器服务。这是一个好主意,由于无法跨配置文件共享实例,我已经遇到了不希望的副作用。谢谢你的跟进。