尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

AutoMapper 依赖注入(DI)完全指南:AddAutoMapper、服务注册与低层 API 详解

发布时间:2026/9/24 16:23:09

资讯中心
01
ARTICLE

AutoMapper 依赖注入(DI)完全指南:AddAutoMapper、服务注册与低层 API 详解

AutoMapper 依赖注入(DI)完全指南:AddAutoMapper、服务注册与低层 API 详解
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),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。