C# 自动映射如何根据上下文将对象A映射到对象B
呼叫所有汽车制造商大师 我希望能够根据运行时的上下文,以不同的方式将对象A映射到对象B。特别是,我希望在一种映射情况下忽略某些属性,而在另一种情况下映射所有属性 我所经历的是,在不同的映射情况下可以成功调用Mapper.CreateMap,但是,一旦调用了CreateMap,就会设置特定类型对的映射,并且随后不会通过后续的CreateMap调用进行更改,这可能会以不同的方式描述映射 我发现了一篇提倡Mapper.Reset()的博客文章来解决这个问题,然而,Mapper类的静态特性意味着碰撞和崩溃发生只是时间问题 有办法做到这一点吗 我想我需要的是在每个appdomain中调用Mapper.CreateMap一次,然后再调用Mapper.Map,并提示应该包含/排除哪些属性 现在,我正在考虑通过编写一个非静态映射类来更改源代码,该类保存基于实例的映射配置。性能差,但线程安全C# 自动映射如何根据上下文将对象A映射到对象B,c#,automapper,C#,Automapper,呼叫所有汽车制造商大师 我希望能够根据运行时的上下文,以不同的方式将对象A映射到对象B。特别是,我希望在一种映射情况下忽略某些属性,而在另一种情况下映射所有属性 我所经历的是,在不同的映射情况下可以成功调用Mapper.CreateMap,但是,一旦调用了CreateMap,就会设置特定类型对的映射,并且随后不会通过后续的CreateMap调用进行更改,这可能会以不同的方式描述映射 我发现了一篇提倡Mapper.Reset()的博客文章来解决这个问题,然而,Mapper类的静态特性意味着碰撞和崩
我的选择是什么。可以做些什么?Automapper看起来很有前途。映射器类只是配置和映射引擎对象之上的一个薄包装器。您可以创建Configuration/MappingEngine对象的单独实例(仍然使用单例),并根据需要使用您选择的IoC容器加载正确的实例
最好的选择仍然是使用不同的目的地类型。真正支持此功能的真正困难之处在于类型映射固有的层次性。顶级对象可能有映射配置文件,而低级对象则没有。介于两者之间的一些可能拥有或没有,等等。对我来说,更好的设计可能是拥有多个目标类(可能从公共基继承或实现公共接口) 如果未映射属性永远不会在其中一个变体中使用,则可以完全忽略它们(提供编译时保证不会错误使用它们),在访问它们时抛出异常(不如编译时保证好,但有时需要实现完整的接口)或者甚至使用替代值 例如:
public class Source
{
public string Name {get;set;}
public BigEntity {get;set;}
/* other members */
}
public class SourceDTO
{
public string Name {get;set;}
public BigEntity {get;set;}
}
public class SourceSummaryDTO
{
public string Name {get;set;}
}
或者,您可以这样做:
public class SourceSummaryDTO : SourceDTO
{
public string Name {get;set;}
public BigEntity
{
get{throw new NotSupportedException();}
set{throw new NotSupportedException();}
}
}
这样,您就可以像传递SourceSummaryDTO一样传递SourceSummaryDTO
对我来说,有条件地填充属性听起来像是一个麻烦的秘诀——我更希望有明确说明其包含内容的类,尤其是数据传输对象
对我来说,Automapper最好的功能是验证映射,然后知道目标类上的每个属性都将被填充。为了补充Jimmy的答案,下面是在没有静态映射器的情况下使用Automapper所需的代码 自4.2.1版起,Automapper具有经认可的非静态映射器和配置(谢谢Jimmy!)
var config=new-MapperConfiguration(cfg=>{
CreateMap();
});
var mapper=config.CreateMapper();
新版本中还有许多其他有用的选项(例如概要文件)用于创建不同的映射器实例。
你可以在网站上找到所有的细节
(适用于4.1.1版)
//配置
AutoMapper.Mappers.MapperRegistry.Reset();
var autoMapperCfg=new AutoMapper.ConfigurationStore(new TypeMapFactory(),AutoMapper.Mappers.MapperRegistry.Mappers);
var mappingEngine=new AutoMapper.mappingEngine(autoMapperCfg);
autoMapperCfg.Seal();
//用法示例
autoMapperCfg.CreateMap();
var b=映射引擎.Map(a);
(适用于3.2.1版)
//配置
var platformSpecificRegistry=AutoMapper.Internal.PlatformAdapter.Resolve();
platformSpecificRegistry.Initialize();
var autoMapperCfg=new AutoMapper.ConfigurationStore(new TypeMapFactory(),AutoMapper.Mappers.MapperRegistry.Mappers);
var mappingEngine=new AutoMapper.mappingEngine(autoMapperCfg);
//用法示例
autoMapperCfg.CreateMap();
var b=映射引擎.Map(a);
(适用于2.2.1版)
//配置
var autoMapperCfg=new AutoMapper.ConfigurationStore(new AutoMapper.TypeMapFactory(),AutoMapper.Mappers.MapperRegistry.AllMappers());
var mappingEngine=new AutoMapper.mappingEngine(autoMapperCfg);
//用法示例
autoMapperCfg.CreateMap();
var b=映射引擎.Map(a);
@Omu:你和你的“ValueInjector”开始变得很烦人了。您不必使用ValueInjector插件(如果不是ValueInjector)回答每个AutoMapper问题。我个人对此很反感,因为你的策略,我甚至不想看它。这不是一个专业的人。
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<ClassA, ClassB>();
});
var mapper = config.CreateMapper();
// Configuration
AutoMapper.Mappers.MapperRegistry.Reset();
var autoMapperCfg = new AutoMapper.ConfigurationStore(new TypeMapFactory(), AutoMapper.Mappers.MapperRegistry.Mappers);
var mappingEngine = new AutoMapper.MappingEngine(autoMapperCfg);
autoMapperCfg.Seal();
//Usage example
autoMapperCfg.CreateMap<ClassA, ClassB>();
var b = mappingEngine.Map<ClassB>(a);
// Configuration
var platformSpecificRegistry = AutoMapper.Internal.PlatformAdapter.Resolve<IPlatformSpecificMapperRegistry>();
platformSpecificRegistry.Initialize();
var autoMapperCfg = new AutoMapper.ConfigurationStore(new TypeMapFactory(), AutoMapper.Mappers.MapperRegistry.Mappers);
var mappingEngine = new AutoMapper.MappingEngine(autoMapperCfg);
//Usage example
autoMapperCfg.CreateMap<ClassA, ClassB>();
var b = mappingEngine.Map<ClassB>(a);
// Configuration
var autoMapperCfg = new AutoMapper.ConfigurationStore(new AutoMapper.TypeMapFactory(), AutoMapper.Mappers.MapperRegistry.AllMappers());
var mappingEngine = new AutoMapper.MappingEngine(autoMapperCfg);
//Usage example
autoMapperCfg.CreateMap<ClassA, ClassB>();
var b = mappingEngine.Map<ClassB>(a);