如果我想在我的应用程序中支持脚本,那么与仅使用普通的Roslyn脚本引擎相比, scriptcs有什么特别的优势吗?
1 回答
不幸的是,目前还没有太多关于托管脚本的文档,但我会尽量给你一个简短的总结。
在您的应用程序中托管脚本提供了一些普通 Roslyn 没有的功能:
可插拔引擎
虽然 scriptcs 默认带有 Roslyn 和 Mono 引擎,但您可以轻松地将其替换为其他引擎,即F#、LOLcode甚至Brainfuck。
预处理
scriptcs 将处理您的脚本并提取参考(#r
)之类的内容并加载其他脚本(#load
)。最近还引入了 custom ILineProcessor
,它可以让您连接到管道中进行自定义处理。示例处理器可能如下所示:
public class GistLineProcessor : DirectiveLineProcessor
{
protected string DirectiveName
{
return "gist";
}
protected override bool ProcessLine(IFileParser parser, FileParserContext context, string line)
{
var gistId = GetDirectiveArgument(line);
var gistContents = DownloadGistContents(gistId);
parser.ParseScript(gistContents, context);
return true;
}
private static string DownloadGistContents(string gistId)
{
// Download gist contents...
}
}
该处理器将下载一个要点并将其作为脚本的一部分执行,即#gist 12345678
.
NuGet 集成
scriptcs 与 NuGet 集成。这意味着,如果您希望脚本能够使用 NuGet 包,只需安装它们,它们就会自动从包文件夹中加载。
脚本包
脚本包是 scriptcs 删除样板代码的方法。他们可以导入命名空间、引用程序集并通过Require<T>()
. 请参阅 Martin Doms 关于构建 scriptcs 脚本包的优秀博文。有关可用脚本包的完整列表,请参阅脚本包主列表。
REPL
您可能知道,scriptcs 有一个 REPL。这可以在您自己的应用程序中重用以提供交互式脚本会话。
调试
使用 vanilla Roslyn 脚本引擎,您不能很容易地调试脚本。#line
scriptcs 使您能够通过在预处理期间插入的指令使用源映射来调试脚本。
我可能忘记了一些东西,但这些是选择脚本而不是原版 Roslyn 的要点。当涉及到实际托管时,您有两种选择:
ScriptCs.Core
这是一个超轻量级的库,包含了 scriptcs 管道的核心组件。但是,它不包含IScriptEngine
(实际执行代码的引擎)和IInstallationProvider
(安装包的组件,即 NuGet)的实现,它们位于ScriptCs.Hosting和ScriptCs.Engine.Roslyn中。如果你使用这个库,你必须自己完成所有组件的连接,你还需要为引擎和包安装程序提供一个实现。
ScriptCs.Hosting
ScriptCs.Hosting 是在应用程序中托管脚本的便利层。它在 scriptcs.exe 内部使用,并为您完成所有组件的连接(通过Autofac)。它包含包安装程序的 NuGet 实现,默认情况下依赖于ScriptCs.Engine.Roslyn。这是托管 scriptcs 的首选方式,因为它可以ScriptServicesBuilder
轻松替换 scriptcs 的内部服务。有关示例用法,请参见scriptcs 的 Program.cs。
这可能听起来令人困惑,所以如果您有任何问题,请在JabbR、Github或Google Group上提问。