C# 在映射期间添加上下文
我有一个类,它有一个C# 在映射期间添加上下文,c#,automapper,C#,Automapper,我有一个类,它有一个Thing集合,可以通过Id和ThingCollectionId来识别 对应的DtoThing仅包含Id,我想在映射DtoThing到对象时,从全局已知的ThingCollections类加载PropertyNotInDto属性 // sources for mapping public class MyClass { public Guid ThingCollectionId {get;set;} public Dictionary<Thing, My
Thing
集合,可以通过Id
和ThingCollectionId
来识别
对应的DtoThing
仅包含Id
,我想在映射DtoThing
到对象时,从全局已知的ThingCollections
类加载PropertyNotInDto
属性
// sources for mapping
public class MyClass {
public Guid ThingCollectionId {get;set;}
public Dictionary<Thing, MyClassB> Things {get;set;}
}
public class Thing {
public int Id {get;set;}
// other properties
public string PropertyNotInDto {get;set;}
}
// targets for mapping
public class DtoMyClass {
public Guid ThingCollectionId {get;set;}
public Dictionary<DtoThing, DtoMyClassB> Things {get;set;}
}
public class DtoThing {
public int Id {get;set;}
// no other properties are saved in the DtoThing class
}
// global
public class ThingCollections {
public Dictionary<Guid, List<Thing>> ThingCollections {get;}
}
这可以通过DtoMyClass
到MyClass
映射上的IMappingAction
来实现,但这需要我重新构建事物列表,并将映射代码添加到MyDtoClass
而不是DtoThing
// sources for mapping
public class MyClass {
public Guid ThingCollectionId {get;set;}
public Dictionary<Thing, MyClassB> Things {get;set;}
}
public class Thing {
public int Id {get;set;}
// other properties
public string PropertyNotInDto {get;set;}
}
// targets for mapping
public class DtoMyClass {
public Guid ThingCollectionId {get;set;}
public Dictionary<DtoThing, DtoMyClassB> Things {get;set;}
}
public class DtoThing {
public int Id {get;set;}
// no other properties are saved in the DtoThing class
}
// global
public class ThingCollections {
public Dictionary<Guid, List<Thing>> ThingCollections {get;}
}
其中ThingMappingAction
可以访问ThingCollectionId
我目前的做法如下:
CreateMap<DtoThing, Thing>().AdvancedMapping<ThingMappingAction>();
CreateMap<DtoMyClass, MyClass>().AfterMap<MyClassMappingAction>();
...
public MyClassMappingAction : IMappingAction<DtoMyClass, MyClass> {
private ThingCollections ThingCollections {get;}
public MyClassMappingAction(ThingCollections thingCollections){
ThingCollections = thingCollections;
}
public void Process(MyDtoClass source, MyClass target) {
// fix target.Things with ThingCollectionId, Thing.Id and ThingCollections
}
}
CreateMap().AfterMap();
...
公共MyClassMappingAction:ImapingAction{
私有ThingCollections ThingCollections{get;}
公共MyClassMappingAction(ThingCollections ThingCollections){
ThingCollections=ThingCollections;
}
公共作废进程(MyDtoClass源、MyClass目标){
//使用ThingCollectionId、Thing.Id和ThingCollections修复target.Things
}
}
但这尤其令人恼火,因为Thing
在多个属性中使用,并且每个这样的实例都需要特殊的代码,这需要添加到MyClassMappingAction
我通过在BeforeMap
的上下文中添加ThingCollectionId
并使用itypecoverter
再次访问它来实现
CreateMap<DtoMyClass, MyClass>().BeforeMap((dto, myclass, context) => context.Items["ThingCollectionId"] = dto.ThingCollectionId);
CreateMap<DtoThing, Thing>().ConvertUsing<ThingTypeConverter>();
public ThingTypeConverter: ITypeConverter<DtoThing, Thing> {
private ThingCollections ThingCollections {get;}
public MyClassMappingAction(ThingCollections thingCollections){
ThingCollections = thingCollections;
}
public Thing Convert(DtoThing source, Thing destination, ResolutionContext context) {
// Get the correct ThingCollection by ThingCollectionId
var thingCollection = ThingCollections[(Guid)context.Items["ThingCollectionId"]];
// Get the correct Thing from the ThingCollection by its Id
return thingCollection.First(t => t.Id == source.Id);
}
}
CreateMap().BeforeMap((dto,myclass,context)=>context.Items[“ThingCollectionId”]=dto.ThingCollectionId);
CreateMap().ConvertUsing();
公共ThingTypeConverter:ITypeConverter{
私有ThingCollections ThingCollections{get;}
公共MyClassMappingAction(ThingCollections ThingCollections){
ThingCollections=ThingCollections;
}
公共事物转换(数据源、事物目标、ResolutionContext上下文){
//通过ThingCollectionId获取正确的ThingCollection
var thingCollection=ThingCollections[(Guid)context.Items[“ThingCollectionId”];
//通过其Id从ThingCollection获取正确的内容
返回thingCollection.First(t=>t.Id==source.Id);
}
}
这将替换以前使用的AfterMap
调用和MyClassMappingAction
。这样一来,Things
的映射代码a就不包含在MyClass
的映射中,也就不需要再手动重新创建MyClass.Things
字典了。请尝试而不是AfterMap。@LucianBargaoanu感谢您的建议!我仍在想如何在映射配置文件中设置该上下文,而不是在调用Mapper.Map
时设置该上下文。该上下文用于Map调用。对于其他情况,您可以使用DI,或者在映射配置文件中构造解析器实例时只传递值。