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

从字节数组加载Assembly时AppDomain程序集未找到问题求助

解决AppDomain加载字节数组后找不到程序集的问题

我太懂你花30多小时卡在这里的崩溃感了——这个问题其实是AppDomain.Load(byte[])的一个极易踩中的陷阱,咱们一步步把它捋清楚解决掉。

问题根源

你用domain.Load(_myBytes)的时候,这个方法根本不是在你创建的目标AppDomain里加载程序集!它是在调用这个方法的当前AppDomain中加载的,目标AppDomain完全没拿到这个程序集,后续枚举自然会报「AppDomain Assembly not found」。这是官方文档里藏得比较深的细节,很多人第一次用都会踩坑。

解决方案:用目标AppDomain内的代理对象加载

要让程序集真正加载到目标AppDomain里,你需要借助MarshalByRefObject创建一个跨AppDomain的代理类,让加载操作在目标AppDomain内部执行。

步骤1:创建跨AppDomain的加载器类

这个类会在目标AppDomain中实例化,所有加载和枚举操作都由它在目标域内完成:

public class AssemblyLoader : MarshalByRefObject
{
    private Assembly _loadedAssembly;

    // 在目标AppDomain内部加载字节数组形式的程序集
    public void LoadAssembly(byte[] assemblyBytes)
    {
        _loadedAssembly = Assembly.Load(assemblyBytes);
    }

    // 从目标AppDomain中获取所有类型的名称
    public List<string> GetAllTypeNames()
    {
        if (_loadedAssembly == null)
            throw new InvalidOperationException("请先加载程序集");
        
        return _loadedAssembly.GetTypes()
                              .Select(type => type.FullName)
                              .ToList();
    }
}

步骤2:修改主程序逻辑

现在调整你的代码,让目标AppDomain自己去加载程序集:

// 读取dll字节数组并删除原文件
byte[] _myBytes = File.ReadAllBytes(@"D:\Projects\AppDomainTest\plugin.dll");
File.Delete(@"D:\Projects\AppDomainTest\plugin.dll");

// 创建目标AppDomain
var domain = AppDomain.CreateDomain("plugintest", null, null, null, false);

try
{
    // 在目标AppDomain中创建AssemblyLoader的实例(通过透明代理)
    var loader = (AssemblyLoader)domain.CreateInstanceAndUnwrap(
        typeof(AssemblyLoader).Assembly.FullName,
        typeof(AssemblyLoader).FullName
    );

    // 让目标AppDomain自己加载字节数组
    loader.LoadAssembly(_myBytes);

    // 从目标AppDomain获取所有类型
    var typeNames = loader.GetAllTypeNames();
    foreach (var typeName in typeNames)
    {
        Console.WriteLine(typeName);
    }
}
finally
{
    // 用完记得卸载AppDomain(如果不需要保留的话)
    AppDomain.Unload(domain);
}

额外说明

  • 为什么必须用代理?因为AppDomain是隔离的,你不能直接在当前域操作另一个域的对象。MarshalByRefObject会让.NET为你创建一个透明代理,你在当前域调用代理方法时,实际执行逻辑会跑到目标AppDomain里。
  • 如果你需要更多操作(比如创建类型实例),都可以在AssemblyLoader里添加对应的方法,确保所有操作都在目标域内完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:15:32