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

通过Roslyn编译的程序集加载时触发FileNotFoundException问题

解决内存编译程序集加载时找不到RazorLight依赖的问题

我之前也踩过Roslyn动态编译依赖加载的坑,你的情况核心问题很明确:Roslyn编译时的MetadataReference只解决了编译阶段的类型引用问题,但运行时CLR并不知道你指定的RazorLight.dll路径,它会默认从GAC、应用程序目录等常规位置查找,找不到就抛出FileNotFoundException。下面是几个实用的解决方案:

1. 挂钩AssemblyResolve事件手动加载依赖

这是最直接有效的办法,当CLR找不到指定程序集时,我们手动从已知路径加载它。你可以在加载Sample.dll或者初始化RazorLight引擎之前添加这段代码:

using System.Reflection;
using System;

// 注册程序集解析事件
AppDomain.CurrentDomain.AssemblyResolve += (sender, resolveArgs) =>
{
    var targetAssemblyName = new AssemblyName(resolveArgs.Name);
    // 匹配RazorLight程序集(可根据需要精确匹配版本/公钥)
    if (string.Equals(targetAssemblyName.Name, "RazorLight", StringComparison.OrdinalIgnoreCase))
    {
        // 替换为你实际的RazorLight.dll路径
        string razorLightPath = @"C:\Users\favishg\source\repos\Empeon_Reports\Reports\bin\Debug\net461\RazorLight.dll";
        return Assembly.LoadFrom(razorLightPath);
    }
    // 其他依赖如果也有加载问题,可以在这里继续添加处理逻辑
    return null;
};

2. 确认RazorLight版本完全匹配

异常提示找不到RazorLight, Version=2.0.0.0,你需要先确认编译时引用的RazorLight.dll版本确实是2.0.0.0:

  • 右键RazorLight.dll → 属性 → 详细信息,查看"文件版本"和"产品版本"
  • 或者用代码快速验证:
var razorAssembly = Assembly.LoadFrom(@"C:\Users\favishg\source\repos\Empeon_Reports\Reports\bin\Debug\net461\RazorLight.dll");
Console.WriteLine($"RazorLight版本:{razorAssembly.GetName().Version}");

如果版本不匹配,要么更新引用的RazorLight版本,要么在AssemblyResolve事件中用名称匹配(上面的代码已经这么做了,会自动加载你指定路径的版本)。

3. 给编译选项指定CodeBase(进阶)

如果你能直接控制Roslyn的编译过程(比如自定义RazorLight的编译服务),可以在编译选项中设置CodeBase,提前告诉CLR依赖程序集的位置:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

var compileOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
    .WithMetadataImportOptions(MetadataImportOptions.All)
    // 指定RazorLight的路径作为CodeBase
    .WithCodeBase(@"C:\Users\favishg\source\repos\Empeon_Reports\Reports\bin\Debug\net461\RazorLight.dll");

// 后续将这个compileOptions传递给RazorLight的编译逻辑

不过这个方法需要你深入RazorLight的编译配置,如果你用的是默认的RazorLightEngineBuilder,可能需要自定义ICompilationService来替换默认实现。

4. 检查RazorLight的依赖链

有时候异常的根源不是RazorLight.dll本身,而是它依赖的其他组件缺失。你可以用Visual Studio的"依赖项"窗口查看RazorLight.dll的依赖,或者用Dependency Walker工具扫描,确保所有依赖都在CLR能找到的路径下,或者同样通过AssemblyResolve事件处理这些依赖。

另外你提到异常触发在调用assembly.GetCustomAttribute<RazorLightTemplateAttribute>()时,这是因为当CLR尝试访问这个特性类型时,才需要实际加载包含该类型的RazorLight程序集——之前的编译阶段只是用MetadataReference获取了类型信息,并没有真正加载程序集。

内容的提问来源于stack exchange,提问作者Saf-G

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:58:16