.NET MAUI Android Release构建解析IMapper时遇TargetInvocationException
问题背景
在.NET MAUI v9项目中集成AutoMapper v14,按官方文档完成配置:
- 注册AutoMapper:
mauiAppBuilder.Services.AddAutoMapper(typeof(MappingProfile)); - ViewModel构造函数注入IMapper:
public MainPageViewModel(IMapper mapper)
Debug模式运行完全正常,但切换到Release模式时抛出TargetInvocationException,异常栈指向AutoMapper配置表达式的实例化过程。禁用Release构建的AOT和裁剪功能后问题消失,确认是链接器裁剪导致的问题。
已尝试添加TrimmerRootAssembly保留AutoMapper程序集,但异常仍未解决:
<ItemGroup> <TrimmerRootAssembly Include="AutoMapper" RootMode="library" /> </ItemGroup>
解决方案
除了保留AutoMapper程序集,还需针对链接器的裁剪逻辑补充以下配置:
保护自定义映射配置类
新建或修改项目的Properties\linker.xml文件,确保你的MappingProfile不被裁剪:<?xml version="1.0" encoding="UTF-8" ?> <linker> <assembly fullname="你的项目程序集名称"> <type fullname="你的命名空间.MappingProfile" preserve="all" /> </assembly> </linker>增强AutoMapper的裁剪保留规则
在.csproj中添加更全面的保留配置,覆盖AutoMapper及依赖的关键类型:<ItemGroup> <TrimmerRootAssembly Include="AutoMapper" /> <TrimmerRootAssembly Include="System.Linq.Expressions" /> <AotExcludeAssembly Include="AutoMapper" /> </ItemGroup>启用编译时映射生成(推荐)
开启AutoMapper的编译时代码生成功能,彻底规避运行时反射带来的链接器问题:<PropertyGroup> <GenerateMapsAtBuild>true</GenerateMapsAtBuild> </PropertyGroup>该配置会在编译阶段自动生成映射实现代码,无需依赖运行时反射扫描。
调整AOT配置(若需启用AOT)
若必须保留AOT编译,关闭Profiled AOT以避免误裁剪:<PropertyGroup> <AndroidEnableProfiledAot>false</AndroidEnableProfiledAot> </PropertyGroup>
原因分析
Release模式下MAUI的链接器会自动裁剪未被直接引用的代码。AutoMapper依赖反射扫描自定义MappingProfile,而仅通过AddAutoMapper的类型参数引用配置类时,链接器会将其判定为未使用代码并裁剪。同时,AutoMapper内部依赖的表达式树类型、动态创建的配置表达式也可能被误裁剪,最终导致实例化失败。
内容的提问来源于stack exchange,提问作者Dawid

