如何在Roslyn Scripting Engine中向CSharp脚本暴露全局单例?
解决Roslyn脚本无法访问静态单例的问题
我懂你遇到的这个坑——明明已经加了当前程序集的引用,却还是找不到IOManager类型。其实这是Roslyn脚本的常见特性:仅添加程序集引用还不够,必须显式导入对应的命名空间,或者通过配置让脚本上下文识别这些类型。下面给你几个实用的解决方案:
方案1:在脚本内容里直接加命名空间引用
最简单的办法就是在脚本开头补上using语句,指定IOManager所在的命名空间。比如:
var scriptContent = @" using YourAppCore; // 替换成IOManager实际所在的命名空间 IOManager.Instance.DoWork(...); "; var options = ScriptOptions.Default.AddReference(this.GetType().Assembly); var script = CSharpScript.Create(scriptContent, options); await script.RunAsync();
方案2:通过ScriptOptions全局注入命名空间
要是不想修改脚本内容,你可以用ScriptOptions的AddImports方法,把目标命名空间直接注入到脚本的全局上下文里:
var scriptContent = "IOManager.Instance.DoWork(...);"; var options = ScriptOptions.Default .AddReference(this.GetType().Assembly) .AddImports("YourAppCore"); // 替换成实际命名空间 var script = CSharpScript.Create(scriptContent, options); await script.RunAsync();
这样脚本执行时就会自动识别该命名空间下的所有公共类型了。
额外要注意的细节
- 确保
IOManager类的访问修饰符是public,如果是internal,哪怕加了程序集引用,脚本也没法访问它(除非你用InternalsVisibleTo特性开放权限)。 - 要是你的单例是通过依赖注入容器注册的,也可以考虑把容器实例作为全局对象传入脚本上下文,让脚本通过容器获取服务,但这和你想要直接访问静态单例的需求略有不同。
内容的提问来源于stack exchange,提问作者Felix Almesberger
相关产品推荐
相关产品推荐

