找回密码
 立即注册
首页 资源区 代码 使用Roslyn运行C#脚本时如何引用程序集

使用Roslyn运行C#脚本时如何引用程序集

啪炽 2025-5-29 10:51:37
使用Roslyn的CSharpScript类运行C#脚本时,会默认包含一部分程序集,默认包含的程序集引用可以直接使用,而其他程序集则需要额外提供引用。本文简单描述了使用Roslyn的CSharpScript类实运行C#脚本时,如何引用程序集。
情景再现

首先创建一个C#类库,代码很简单,提供一个静态公共方法,打印一个字符串
  1. namespace ClassLibrary1
  2. {
  3.     public class Class1
  4.     {
  5.         public static void TestMethod()
  6.         {
  7.             Console.WriteLine("Class1:TestMethod");
  8.         }
  9.     }
  10. }
复制代码
然后在创建一个C#控制台,引用类库,然后分别通过普通方式和脚本化的方式调用TestMethod
  1. using ClassLibrary1;
  2. using Microsoft.CodeAnalysis.CSharp.Scripting;
  3. namespace ConsoleApp1
  4. {
  5.     internal class Program
  6.     {
  7.         static void Main(string[] args)
  8.         {
  9.             Class1.TestMethod();
  10.             var code2 = @"Class1.TestMethod();";
  11.             try
  12.             {
  13.                 CSharpScript.Create(code2).RunAsync().GetAwaiter().GetResult();
  14.             }
  15.             catch (Exception e)
  16.             {
  17.                 Console.WriteLine(e);
  18.                 throw;
  19.             }
  20.         }
  21.     }
  22. }
复制代码
结果如下
  1. Class1::TestMethod.Call directly
  2. Microsoft.CodeAnalysis.Scripting.CompilationErrorException: (1,1): error CS0103: 当前上下文中不存在名称“Class1”
  3.    在 Microsoft.CodeAnalysis.Scripting.ScriptBuilder.ThrowIfAnyCompilationErrors(DiagnosticBag diagnostics, DiagnosticFormatter formatter) 位置 /_/src/Scripting/Core/ScriptBuilder.cs:行号 105
  4.    在 Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T](ScriptCompiler compiler, Compilation compilation, Boolean emitDebugInformation, CancellationToken cancellationToken) 位置 /_/src/Scripting/Core/ScriptBuilder.cs:行号 93
  5.    在 Microsoft.CodeAnalysis.Scripting.Script`1.GetExecutor(CancellationToken cancellationToken) 位置 /_/src/Scripting/Core/Script.cs:行号 392
  6.    在 Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, Func`2 catchException, CancellationToken cancellationToken) 位置 /_/src/Scripting/Core/Script.cs:行号 492
  7.    在 ConsoleApp1.Program.Main(String[] args) 位置 D:\Projects\CSharp Projects\WpfApp1\ConsoleApp1\Program.cs:行号 15
复制代码
可以看到,CSharpScript找不到Class1,即使我们加上using ClassLibrary1;结果也是一样。
问题解决

要让CSharpScript能够找到我们的程序集,需要使用CSharpScript.Create方法的options参数传入一个ScriptOptions类型的对象,并且利用ScriptOptions的WithRefrences方法添加程序集引用。
修改后的代码如下:
  1. using System.Reflection;
  2. using ClassLibrary1;
  3. using Microsoft.CodeAnalysis.CSharp.Scripting;
  4. using Microsoft.CodeAnalysis.Scripting;
  5. namespace ConsoleApp1
  6. {
  7.     internal class Program
  8.     {
  9.         static void Main(string[] args)
  10.         {
  11.             Class1.TestMethod("Call directly");
  12.             var code2 = @"
  13. using ClassLibrary1;
  14. Class1.TestMethod(""Call with scripting"");
  15. ";
  16.             var assembly = Assembly.Load("ClassLibrary1");
  17.             //如果当前的AppDomain中没有加载过该程序集,则需要使用Assembly.LoadFrom来加载
  18.             //确保程序集的路径正确,以及相关的依赖项也在正确的位置
  19.             //var assembly = Assembly.LoadFrom("ClassLibrary1.dll");
  20.             var options = ScriptOptions.Default.WithReferences(assembly);
  21.             CSharpScript.Create(code2, options).RunAsync().GetAwaiter().GetResult();
  22.         }
  23.     }
  24. }
复制代码
WithReference方法也接受string类型和MetadataReference类型的参数,例如,上述代码对WithReference方法的调用也可以使用下面两种方式(两种方式都需要使用绝对路径)
  1. var options = ScriptOptions.Default.WithReferences(@"C:\ClassLibrary1");
复制代码
  1. var metaRef = MetadataReference.CreateFromFile(@"C:\ClassLibrary1");
  2. var options = ScriptOptions.Default.WithReferences(metaRef);
复制代码
运行后的结果如下:
  1. Class1::TestMethod.Call directly
  2. Class1::TestMethod.Call with scripting
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册