AutoMapper 依赖注入DI完全指南AddAutoMapper、服务注册与低层 API 详解【免费下载链接】AutoMapperA convention-based object-object mapper in .NET.项目地址: https://gitcode.com/gh_mirrors/au/AutoMapper导读本文基于 AutoMapper 官方文档的 Dependency Injection 章节结合当前仓库源码src/AutoMapper/ServiceCollectionExtensions.cs、src/AutoMapper/Configuration/MapperConfigurationExpression.cs等系统讲解如何在 ASP.NET Core 中通过AddAutoMapper完成配置装配与依赖注入包括程序集扫描、Profile 注册、IMapper/IConfigurationProvider的生命周期管理、八类可自动注册的服务类型以及不依赖容器的低层ConstructServicesUsingAPI。读完本文你将能在自己的 .NET 项目中熟练接入 AutoMapper 的 DI 机制并理解其内部注册逻辑与使用边界。一、版本背景13.0 之后 DI 支持内置于核心包从13.0 版本开始AddAutoMapper扩展方法已经成为 AutoMapper 核心包AutoMapper的一部分原先独立的AutoMapper.Extensions.Microsoft.DependencyInjection包已被停止维护、不再发布。这一点在仓库的 13.0-Upgrade-Guide.md 中有明确记载AddAutoMapperis part of the core package and the DI package is discontinued。因此现代项目中你只需要引用核心包即可直接使用Microsoft.Extensions.DependencyInjection命名空间下的AddAutoMapper扩展方法。仓库中的实现位于 ServiceCollectionExtensions.cs其命名空间正是Microsoft.Extensions.DependencyInjection意味着它能无缝融入标准 ASP.NET Core 的容器体系。二、ASP.NET Core 中的标准用法2.1 用 Profile 定义配置AutoMapper 的映射配置推荐以 Profile配置文件类为单位组织。每个 Profile 继承自AutoMapper.Profile并在构造函数或Configure方法中调用CreateMap等 API 声明映射规则。关于 Profile 的完整说明参见文档 Configuration.md 中的 Profile Instances 一节。仓库中 Profile.cs 的源码展示了 Profile 的核心结构它持有TypeMapConfigs映射配置集合并通过CreateMapTSource, TDestination()、CreateProjectionTSource, TDestination()等方法将映射表达式加入集合。2.2 在启动时调用 AddAutoMapper在Startup.ConfigureServices或 .NET 6 的Program.cs中调用IServiceCollection的扩展方法AddAutoMapper并告知 AutoMapper 在哪些程序集中查找 Profileservices.AddAutoMapper(cfg { }, profileAssembly1, profileAssembly2 /*, ...*/);其中profileAssembly1、profileAssembly2是System.Reflection.Assembly实例也可以使用marker type标记类型写法由 AutoMapper 自动推导其所在的程序集services.AddAutoMapper(cfg { }, typeof(ProfileTypeFromAssembly1), typeof(ProfileTypeFromAssembly2) /*, ...*/);两种写法在源码中都有对应的重载ServiceCollectionExtensions.cs 提供了params Assembly[]与params Type[]两组入口其中Type[]重载通过t.GetTypeInfo().Assembly将标记类型转换为程序集再交给统一的内部方法处理。cfg参数是一个ActionIMapperConfigurationExpression委托可以在这里直接补充额外的全局配置例如cfg.CreateMapSource, Destination()、cfg.AddProfileTProfile()等。仓库还额外提供了一个接收ActionIServiceProvider, IMapperConfigurationExpression的重载让你在配置阶段就能从容器解析服务。2.3 注入并消费 IMapper完成注册后即可在任意服务或控制器中注入IMapper并在运行时执行映射public class EmployeesController { private readonly IMapper _mapper; public EmployeesController(IMapper mapper) _mapper mapper; // 使用 _mapper.Map 或 _mapper.ProjectTo }IMapper接口定义在 Mapper.cs 中提供了MapTSource, TDestination、MapTDestination(object source)、带ActionIMappingOperationOptions的重载等一系列映射入口。三、AddAutoMapper 的注册机制生命周期与装配细节结合 ServiceCollectionExtensions.cs 的AddAutoMapperClasses私有方法可以梳理出AddAutoMapper内部实际完成的四件事收集配置若传入configAction将其通过services.AddOptionsMapperConfigurationExpression().ConfigureIServiceProvider(...)注册为IOptions配置源若传入程序集则调用options.AddMaps(assembliesToScan)扫描这些程序集中的 Profile 与[AutoMap]特性标注的类参见 MapperConfigurationExpression.cs 中 AddMaps 的说明。过滤并注册服务类程序集会先过滤掉动态程序集和 AutoMapper 自身的程序集a.IsDynamic a ! typeof(Mapper).Assembly再筛选出实现了 AutoMapper 服务接口的具体类逐个用TryAddTransient注册TryAdd语义可避免重复注册。注册 IConfigurationProvider 为单例Singleton工厂方法从容器解析IOptionsMapperConfigurationExpression和ILoggerFactory构造MapperConfiguration。这与 MapperConfiguration.cs 中MapperConfiguration(MapperConfigurationExpression, ILoggerFactory)的构造函数一一对应——IConfigurationProvider持有全部编译好的执行计划天然适合全局复用。注册 IMapperIMapper的默认生命周期是Transient且通过sp.GetService容器解析作为其服务构造器IMapper的注册还带有一个防重复检查if (services.Any(sd sd.ServiceType typeof(IMapper))) return services;保证重复调用AddAutoMapper不会产生双份注册。3.1 自定义 IMapper 生命周期IMapper的默认生命周期为Transient每次解析都新建实例该默认值定义在 MapperConfigurationExpression.cspublic ServiceLifetime ServiceLifetime { get; set; } ServiceLifetime.Transient;。你也可以通过带ServiceLifetime参数的重载改成Singleton或Scopedservices.AddAutoMapper(cfg { }, assemblies, ServiceLifetime.Singleton);仓库测试 ServiceLifetimeTests.cs 对此做了验证默认调用AddAutoMapper(_ { })后IMapper的ServiceDescriptor.Lifetime为Transient传入ServiceLifetime.Singleton后则变为Singleton。注意IConfigurationProvider始终是Singleton只有IMapper的生命周期可配置。由于IMapper内部持有IConfigurationProvider即使IMapper是 Transient其执行计划仍被全局缓存复用。测试 Integrations/ServiceLifetimeTests.cs 还演示了把注入IMapper的服务注册为单例的完整用法。四、Autofac 及其他 DI 容器Autofac社区提供了第三方包AutoMapper.Contrib.Autofac.DependencyInjection可供尝试。其他 DI 引擎AutoMapper 官方维护过一个 DI 示例合集AutoMapper/wiki/DI-examples涵盖多种容器的接入方式。对于不在上述包支持范围内的容器核心思路是使用下一节介绍的低层 API 手动接线。五、低层 APIConstructServicesUsing 与静态服务定位不依赖AddAutoMapper时AutoMapper 允许为自定义值解析器Custom Value Resolvers、自定义类型转换器Custom Type Converters、值转换器Value Converters和基于类的条件Class-based Conditions通过静态服务定位的方式提供构造函数依赖var configuration new MapperConfiguration(cfg { cfg.ConstructServicesUsing(ObjectFactory.GetInstance); cfg.CreateMapSource, Destination(); }, loggerFactory);ConstructServicesUsing接收一个FuncType, object工厂委托用于在映射过程中创建上述服务类型实例。该 API 有三层使用位置作用范围依次收窄配置级IMapperConfigurationExpression.ConstructServicesUsingMapperConfigurationExpression.cs默认实现是Activator.CreateInstance见该文件第 104 行_serviceCtor的初值即未配置时通过反射无参构造。Mapper 实例级MapperConfiguration.CreateMapper(FuncType, object serviceCtor)MapperConfiguration.cs可为特定 Mapper 实例指定服务工厂。单次映射级IMappingOperationOptions.ConstructServicesUsingIMappingOperationOptions.cs用于子容器/嵌套容器场景。其实现会把新工厂与原工厂做回退串联ServiceCtor t constructor(t) ?? ctor(t)见该文件第 58-62 行即先尝试新工厂失败返回 null时回退到上层工厂。使用ConstructServicesUsing时值解析器/转换器上的构造函数参数将由该工厂按Type解析后注入。这是把 AutoMapper 手动桥接到任意 IoC 容器的标准方式也是AddAutoMapper内部机制的底层形态。六、自动类注册八类服务接口一览调用AddAutoMapper并指定程序集后AutoMapper 会从这些程序集中自动发现以下接口的实现类并以ServiceLifetime.Transient注册到容器接口用途IValueResolverTSource, TDestination, TDestMember自定义成员值解析器IMemberValueResolverTSource, TDestination, TSourceMember, TDestMember带源成员参数的自定义值解析器ITypeConverterTSource, TDestination自定义类型转换器IValueConverterTSourceMember, TDestinationMember值转换器IDestinationFactoryTSource, TDestination目标对象工厂IConditionTSource, TDestination, TMember基于类的条件判断IPreConditionTSource, TDestination映射前置条件IMappingActionTSource, TDestination映射动作Before/After Map源码中的判定逻辑一目了然ServiceCollectionExtensions内维护了一个开放泛型数组AmTypes [typeof(IValueResolver,,), typeof(IMemberValueResolver,,,), typeof(ITypeConverter,), typeof(IValueConverter,), typeof(IDestinationFactory,,), typeof(ICondition,,), typeof(IPreCondition,), typeof(IMappingAction,)]ServiceCollectionExtensions.cs随后对每个扫描到的具体类执行type.GetGenericInterface(openType) ! null判断第 88 行命中的即调用services.TryAddTransient(type)注册。也就是说只要你的类实现了上述任一接口无需任何额外注册代码容器就能在映射时将其解析注入。需要注意这些服务接口的判定依赖类型恰好实现对应的开放泛型接口。如果你的实现类还实现了其他接口如IDisposable并不影响注册但如果同时实现多个 AutoMapper 服务接口它们会被分别注册。七、Queryable ExtensionsProjectTo 与 DI 的边界从 8.0 版本开始可以调用IMapper.ProjectTo进行查询投影更早的版本则需要把配置对象传给扩展方法IQueryable.ProjectToT(IConfigurationProvider)。必须特别强调的是ProjectTo比Map能力更受限投影是在 LINQ 提供程序如 EF Core 翻译成 SQL层面完成的只支持底层提供程序允许的映射选项详细说明见 Queryable-Extensions.md 的 Supported Mapping Options 一节。因此在ProjectTo场景下不能像Map那样使用依赖注入的值解析器和转换器——因为查询翻译发生在数据库端无法执行任意 C# 服务代码。如果确实需要服务参与计算应退回到内存映射Map或在投影前先把数据取回内存。这一点也解释了为何IMapper.ProjectTo只依赖IConfigurationProvider即可工作投影构建只读取映射配置不触达服务容器。IConfigurationProvider可通过容器直接解析也可通过IMapper.ConfigurationProvider属性获取见 ServiceCollectionExtensions.cs 的注释说明。八、实战建议与常见坑程序集扫描的过滤规则AddAutoMapper会自动跳过动态程序集和 AutoMapper 自身程序集a ! typeof(Mapper).Assembly避免把 AutoMapper 内部类型误注册无需你手动处理。重复调用 AddAutoMapper 是安全的服务类注册使用TryAddTransientIMapper注册有防重复检查多次调用不会产生重复注册或异常。IMapper 生命周期与作用域的匹配默认Transient最安全适用于大多数 Web 场景若改为Singleton需注意IMapper中不应捕获 scoped 服务。仓库测试已验证单例服务注入IMapper后仍可在作用域内正常映射。低层 API 与容器二选一使用AddAutoMapper时无需也不应再手动ConstructServicesUsing二者是容器集成与手工接线的两种方案混用可能造成解析行为不一致。ProjectTo 与 DI 不兼容投影查询中不要依赖值解析器/转换器的容器注入改用可在 LINQ 表达式树中表达的映射方式。结语AutoMapper 的 DI 支持在 13.0 之后彻底融入核心包AddAutoMapper承担了程序集扫描 → Profile 装配 → 八类服务接口自动注册 →IConfigurationProvider单例 IMapper可配置生命周期的全部职责ConstructServicesUsing则为非标准容器提供了等价的低层接入点。理解这两条路径及其在ProjectTo上的边界即可在真实项目中安全、高效地使用 AutoMapper 的依赖注入能力。【免费下载链接】AutoMapperA convention-based object-object mapper in .NET.项目地址: https://gitcode.com/gh_mirrors/au/AutoMapper创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
ParlAI JsonFile 任务:零代码加载自定义 JSON 对话数据并快速训练评估 NLP人工智能深度学习 【免费下载链接】ParlAI A framework for training and evaluating AI models on a variety of openly available dialogue datasets. 项目地址: https://gitcode.com/gh_mirrors/pa/ParlAI 点击查看 免费下载 导读
ParlAI 内置的 jsonfile 任… · 2026/9/24 16:23:03
GEO优化选型避坑指南:成本逻辑、路线对比、认知误区与行业趋势复盘 1. 引言区别于传统SEO的固定排名逻辑,GEO优化依托大模型语义识别、内容采信、智能推荐机制,重构了品牌AI场景流量获取逻辑。赛道热度攀升的同时,行业乱象随之显现:市场报价从每月数千元至数万元跨度极大,服务标准不统一… · 2026/9/24 18:42:53
Chrome扩展实战:京东金融浙商金价实时监控插件开发 我平时有囤点黄金的习惯,京东金融上的浙商银行积存金产品一直有在关注,但是那个价格页不会自己刷新,行情一波动就得手动切过去看,赶上工作忙或者盯盘盯久了,特别容易错过自己想入手的点位。后来我干脆花了一个周末&… · 2026/9/24 18:42:47
宽带瑞利衰落信道下OFDM与OTFS误码率对比:循环前缀的关键作用 简介:针对宽带瑞丽衰减信道下不同调制波形的误码率对比需求,这份MATLAB仿真包提供了OFDM、OTFS、C-OFDM、C-OTFS四种方案在16QAM调制下的完整实现,适合本硕博学生及科研人员作为通信课程设计与算法验证的参考。压缩包共10个文件,含… · 2026/9/24 18:42:47
车载贴片天线模块选型指南:从关键参数到应用与实测 入行做车载通信硬件这十几年,我经手过的贴片天线模块项目不下几十个。从早期的单频 GPS 陶瓷天线,到如今集成了 4G/5G、Wi-Fi、蓝牙、V2X、卫星定位的多频组合方案,车载贴片天线模块已经成了整车电子架构里不可或缺的基础件。很多人拿到选型表… · 2026/9/24 18:42:47
2026开发者效率作战地图:AI工具如何嵌入真实开发流 1. 这不是工具清单,而是一份2026年真实开发现场的效率作战地图你有没有过这样的时刻:凌晨两点,盯着一段循环嵌套三层、变量名全是temp1temp2res的遗留代码,光是理解逻辑就花了47分钟;Git提交前反复删改注释,… · 2026/9/24 18:42:47
宏智树AI实测:从文献管理到降AIGC痕迹的学术写作全流程 每年一到毕业季或者项目结题季,“写论文软件哪个好”这个问题就被反复翻出来。市面上的AI写作工具确实多到让人眼花缭乱,有能对话生成内容的、有做翻译润色的、有专门降查重率的,但真到了自己动手写一篇需要严谨结构、扎实文献支撑的学术论文… · 2026/9/24 18:42:47
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44