我有一个源生成器,允许用户提供一些代码块来配置生成器。然后我通过 CSharpCompilation 基础设施编译并运行它。它在 Windows 上运行良好,但在 Mac 上停止运行。它在
Assembly.Load(...)
上失败,我还注意到有一条警告,禁止在源生成器中使用 Assembly.Load。有没有一种方法可以在适用于所有平台的源代码生成器中编译和运行一段用户定义的代码?
在源生成器中运行用户定义的代码可能很棘手,特别是考虑到约束和平台差异。以下是您的选择和一些潜在解决方案的概述。
Assembly.Load 的问题
安全性和稳定性:Assembly.Load 会带来安全风险 和稳定性问题,这就是为什么它通常不被鼓励, 特别是在像源生成器这样需要 稳定的构建过程。
平台差异:不同的操作系统可能有 对组件的不同处理,这可能导致 您遇到的不一致之处。
解决方案 1.使用Roslyn脚本执行脚本:
您可以使用Roslyn脚本来执行用户定义的代码。这个可以 为运行代码提供更安全、更受控的环境。
Roslyn 脚本可跨平台工作并避免使用 Assembly.Load。
using Microsoft.CodeAnalysis.Scripting;
public async Task<object> ExecuteUserCodeAsync(string code)
{
var options = ScriptOptions.Default
.WithReferences(AppDomain.CurrentDomain.GetAssemblies())
.WithImports("System", "System.Linq", "System.Collections.Generic");
try
{
var result = await CSharpScript.EvaluateAsync(code, options);
return result;
}
catch (Exception ex)
{
// Handle exceptions gracefully
Console.WriteLine($"Error: {ex.Message}");
return null;
}
}
2 - 单独的进程执行:
3- 安全考虑:
4 - 避免使用“Assembly.Load”:
结论
通过使用Roslyn脚本或在单独的进程中执行代码,您可以实现跨平台代码执行,同时保持安全性和稳定性。这些方法避免使用 Assembly.Load,通常建议在源生成器中避免使用。