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

.NET Core WPF迁移中Activator.CreateInstanceFrom依赖加载失败

问题分析与解决方案

为什么指定DLL路径后,依赖不会在同一子目录查找?

.NET(包括.NET Core/.NET 5+)的程序集加载机制中,默认的依赖探测路径不包含被加载程序集自身所在的子目录。当你用Activator.CreateInstanceFrom加载subFolder下的目标DLL时,CLR会优先在应用基目录(主程序所在目录)、系统全局程序集缓存、NuGet包缓存等标准路径中查找该DLL的依赖,不会自动将目标DLL所在的subFolder加入依赖探测路径——这就是依赖找不到的核心原因。

而.NET Framework中默认加载行为会包含被加载程序集的目录,这也是迁移后行为产生差异的关键。

如何让程序持续在子目录查找所有依赖?

方案1:完善AssemblyResolve事件处理(兼容现有代码)

你当前的AssemblyResolve事件逻辑已经覆盖了从subFolder加载依赖的核心,可以优化细节提升可靠性:

  • 直接拼接路径查找匹配的DLL文件,避免遍历所有文件提升效率
  • 简化大小写匹配逻辑
  • 使用更明确的加载方式确保路径正确

优化后的代码示例:

private void LoadAssembly()
{
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

    var pathToDll = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "subFolder", "fileNameOfDll.dll");
    Activator.CreateInstanceFrom(pathToDll, "fullTypeName");
}

private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    var assemblyName = new AssemblyName(args.Name);
    var targetPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "subFolder", $"{assemblyName.Name}.dll");

    if (File.Exists(targetPath))
    {
        // 加载指定路径的程序集
        return Assembly.LoadFrom(targetPath);
    }

    // 找不到则返回null,让CLR继续尝试其他探测路径
    return null;
}

方案2:使用.NET Core原生的AssemblyLoadContext(推荐)

AssemblyLoadContext是.NET Core引入的程序集加载上下文机制,比AppDomain事件更灵活可控,适合自定义加载路径的场景:

  1. 创建自定义加载上下文,绑定依赖探测路径
  2. 通过该上下文加载目标程序集,其所有依赖会自动在指定路径查找

代码示例:

using System.Runtime.Loader;

private void LoadAssembly()
{
    var subFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "subFolder");
    
    // 创建自定义加载上下文,设置依赖解析逻辑
    var loadContext = new AssemblyLoadContext(null, isCollectible: false);
    loadContext.Resolving += (ctx, name) =>
    {
        var dllPath = Path.Combine(subFolderPath, $"{name.Name}.dll");
        return File.Exists(dllPath) ? ctx.LoadFromAssemblyPath(dllPath) : null;
    };

    // 加载目标程序集并创建实例
    var targetDllPath = Path.Combine(subFolderPath, "fileNameOfDll.dll");
    var assembly = loadContext.LoadFromAssemblyPath(targetDllPath);
    var instance = assembly.CreateInstance("fullTypeName");
}

这种方式的优势是:加载上下文与主程序隔离,不会干扰主程序集的加载逻辑,且依赖探测逻辑更清晰,适配.NET Core/WPF的原生环境。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:15:09