You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8中AOT发布程序调用Assembly.LoadFile抛异常,如何动态加载

AOT编译后加载自定义程序集的解决方案

问题背景

一段简单的动态加载代码:

var r = Assembly.LoadFile("c:\\assembly.dll");

在未设置<PublishAot>true</PublishAot>发布时可正常运行,但开启AOT编译发布后,会抛出如下异常:

Unhandled Exception: System.PlatformNotSupportedException: Operation is not supported on this platform.
at Internal.Reflection.Execution.AssemblyBinderImplementation.Bind(String, AssemblyBindResult&, Exception&) + 0x34
at System.Reflection.Runtime.Assemblies.RuntimeAssemblyInfo.GetRuntimeAssemblyFromPath(String) + 0x4c
at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String) + 0x6d
at System.Reflection.Assembly.LoadFile(String) + 0x12c
at Program.

$(String[] args) + 0x24
at app!+0x11b1c0

本文针对「AOT编译同时加载自定义程序集」的需求给出可行方案。

原因说明

.NET NativeAOT是将IL提前编译为原生机器码的编译模式,编译时会把所有依赖程序集整合到最终可执行文件中,并且移除了运行时JIT编译组件。而Assembly.LoadFile这类动态加载API依赖JIT来编译加载进来的IL代码,AOT环境下没有JIT支持,因此直接调用会抛出平台不支持异常。

可行解决方案

1. 使用NativeAOT插件机制(官方推荐)

.NET 7及以上版本的NativeAOT支持插件系统,允许AOT主程序加载同样经AOT编译的插件程序集:

  • 把待加载的程序集做成AOT插件项目,项目文件配置:
    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <PublishAot>true</PublishAot>
        <IsAotPlugin>true</IsAotPlugin>
      </PropertyGroup>
    </Project>
    
  • 主程序中加载插件:
    using System.Runtime.Loader;
    
    var pluginPath = "c:\\assembly.dll";
    var pluginAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(pluginPath);
    // 后续通过反射调用插件中的类型和方法(需提前定义共享契约,比如接口)
    
    注意:插件必须和主程序使用相同.NET版本,且同样以AOT编译;插件中的调用逻辑需要提前在主程序中定义契约(如共享接口),否则反射调用会受限。

2. 改用ReadyToRun编译(兼容传统动态加载)

如果必须加载未经AOT编译的IL程序集,可以放弃完全NativeAOT,改用ReadyToRun编译——它会提前编译大部分代码,但保留JIT编译器用于动态加载场景:

<PropertyGroup>
  <PublishReadyToRun>true</PublishReadyToRun>
  <!-- 不要设置PublishAot -->
</PropertyGroup>

缺点是生成的可执行文件体积更大、启动速度略慢,但能兼容Assembly.LoadFile这类传统动态加载API。

3. 预定义契约+代码生成(复杂场景适配)

若必须使用NativeAOT,且待加载程序集的逻辑结构固定,可以通过源码生成工具(如Source Generator)在编译阶段将插件逻辑整合到主程序中。这种方式灵活性较低,仅适用于插件逻辑可提前定义的场景。

总结

  • 优先选择NativeAOT插件机制,这是官方为AOT场景提供的动态扩展方案;
  • 若需加载普通IL程序集,改用ReadyToRun编译模式;
  • 完全NativeAOT环境下无法直接加载未编译为原生码的IL程序集,因为JIT组件已被移除。

内容的提问来源于stack exchange,提问作者Starl1ght

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 10:37:20