首页 > 其他分享 > Roslyn Scripting APIs

Roslyn Scripting APIs

时间:2023-10-06 09:05:21浏览次数:47  
标签:脚本 await script C# APIs CSharpScript Roslyn var Scripting

Net 编译器平台--- Roslyn Scripting APIs

  合集 - 小工具(8)   1.Net 编译器平台 --- Roslyn07-07 2.Net 编译器平台--- Roslyn Scripting APIs07-08 3.UI自动化 --- 微软UI Automation07-094.UI自动化 --- UI Automation 基础详解07-105.工具 --- IL指令集解释07-216.基准测试工具 --- BenchmarkDotNet07-217.小工具 --- 百度翻译API翻译工具08-138.小工具 --- 树形展示多属性复杂结构类08-13 收起  

引言

上一篇中.Net 编译器平台 --- Roslyn,介绍了Roslyn的各项功能,包括公开API,使用语法,使用语义,使用工作区等功能。

那么回到上一篇中提到的问题,实现类似这样的功能(以下代码为伪代码):

string scriptText = "int a = 1;int b = 2; return a+b ;";

var result = Script.Run(scriptText);

就用到了上一篇提到的 Scripting APIs,还是先了解一下Roslyn提供的 Scripting APIs 有哪些。

官方文档(https://github.com/dotnet/roslyn/blob/main/docs/wiki/Scripting-API-Samples.md) 还是英文版,还是先将他翻译为中文,以下内容为译文。

Scripting APIs Samples

脚本 API 可以让 .NET 应用程序实例化一个 C# 引擎,并针对由宿主提供的对象执行代码片段。以下是使用脚本 API 并进行一些常见示例的入门示例。您也可以查看脚本 API 的源代码。

请注意,作为一个语言模型,我无法提供实时的源代码示例或链接到具体的源代码。但是,您可以参考 Microsoft 的官方文档和示例来了解如何使用脚本 API 并查看相关源代码。

支持的平台

脚本 API 需要桌面版 .NET Framework 4.6+ 或 .NET Core 1.1(自 Roslyn v2.0.0-rc3、Visual Studio 2017 RC3 起支持)。

脚本 API 无法在通用 Windows 应用程序和 .NET Native 中使用,因为应用程序模型不支持在运行时加载生成的代码。

开始准备

安装 Scripting API NuGet 包:

Install-Package Microsoft.CodeAnalysis.CSharp.Scripting

示例代码

以下示例代码中需要添加引用 using Microsoft.CodeAnalysis.CSharp.Scripting;

应用场景:

  • 评估一个C#表达式(Evaluate a C# expression)
  • 评估一个C#表达式(强类型)(Evaluate a C# expression(strongly-typed))
  • 带错误处理的评估C#表达式(Evaluated a C# expression with error handling)
  • 添加引用(Add references)
  • 添加命名空间和类型导入(Add namespace and type imports)
  • 为脚本参数化(Parameterize a script)
  • 创建和构建一个C#脚本,并多次执行(Create&build a C# script and execute it multiple times)
  • 创建一个指向脚本的委托(Create a delegate to a script)
  • 运行一个C#代码片段并检查定义的脚本变量(Run a C# snippet and inspect defined script variables)
  • 将代码片段链接成一个脚本(Chain code snippets to form a script)
  • 从先前状态继续执行脚本(Continue script execution from a previous state)
  • 创建和分析一个C#脚本(Create and analyze a C# script)
  • 自定义程序集加载(Customize assembly loading)

评估一个C#表达式(Evaluate a C# expression)

object result = await CSharpScript.EvaluateAsync("1 + 2");

评估一个C#表达式(强类型)(Evaluate a C# expression(strongly-typed))

int result = await CSharpScript.EvaluateAsync<int>("1 + 2");

带错误处理的评估C#表达式(Evaluated a C# expression with error handling)

try
{
    Console.WriteLine(await CSharpScript.EvaluateAsync("2+2"));
}
catch (CompilationErrorException e)
{
    Console.WriteLine(string.Join(Environment.NewLine, e.Diagnostics));
}

添加引用(Add references)

var result = await CSharpScript.EvaluateAsync("System.Net.Dns.GetHostName()", 
ScriptOptions.Default.WithReferences(typeof(System.Net.Dns).Assembly)); 

添加命名空间和类型导入(Add namespace and type imports)

在下面的代码中,WithImports("System.IO")将 using System.IO; 添加到脚本选项中,使得可以在脚本代码中直接引用 System.IO 命名空间的类型,而无需使用限定符。

var result = await CSharpScript.EvaluateAsync("Directory.GetCurrentDirectory()"), 
                                ScriptOptions.Default.WithImports("System.IO"));

同样地,WithImports("System.Math") 将 using static System.Math; 添加到脚本选项中,使得可以在脚本代码中直接引用 System.Math 类型的成员,而无需使用限定符。

var result = await CSharpScript.EvaluateAsync("Sqrt(2)", 
                                ScriptOptions.Default.WithImports("System.Math"));

为脚本参数化(Parameterize a script)

public class Globals
{
    public int X;
    public int Y;
}

var globals = new Globals { X = 1, Y = 2 };

Console.WriteLine(await CSharpScript.EvaluateAsync<int>("X+Y", globals: globals));

:::tip{title="提示"}
目前,Globals 类型必须在从文件加载的程序集中定义。如果程序集在内存中(包括在交互式窗口中执行示例时),脚本将无法访问该类型。请参阅此处的问题。
:::

创建和构建一个C#脚本,并多次执行(Create&build a C# script and execute it multiple times)

var script = CSharpScript.Create<int>("X*Y", globalsType: typeof(Globals));

script.Compile();

for (int i = 0; i < 10; i++)
{
    Console.WriteLine((await script.RunAsync(new Globals { X = i, Y = i })).ReturnValue);
} 

创建一个脚本的委托(Create a delegate to a script)

该委托不会保持编译资源(语法树等)处于活动状态。

var script = CSharpScript.Create<int>("X*Y", globalsType: typeof(Globals));

ScriptRunner<int> runner = script.CreateDelegate();

for (int i = 0; i < 10; i++)
{
    Console.WriteLine(await runner(new Globals { X = i, Y = i }));
} 

运行一个C#代码片段并检查定义的脚本变量(Run a C# snippet and inspect defined script variables)

var state = await CSharpScript.RunAsync<int>("int answer = 42;");

foreach (var variable in state.Variables)
     Console.WriteLine($"{variable.Name} = {variable.Value} of type {variable.Type}");

将代码片段链接成一个脚本(Chain code snippets to form a script)

var script = CSharpScript.
            Create<int>("int x = 1;").
            ContinueWith("int y = 2;").
            ContinueWith("x + y");

Console.WriteLine((await script.RunAsync()).ReturnValue); 

从先前状态继续执行脚本(Continue script execution from a previous state)

var state = await CSharpScript.RunAsync("int x = 1;");
state = await state.ContinueWithAsync("int y = 2;");
state = await state.ContinueWithAsync("x+y");

Console.WriteLine(state.ReturnValue);

创建和分析一个C#脚本(Create and analyze a C# script)

using Microsoft.CodeAnalysis;

var script = CSharpScript.Create<int>("3");
Compilation compilation = script.GetCompilation();
//do stuff

编译(Compilation)提供了对完整的 Roslyn API 集合的访问。

自定义程序集加载(Customize assembly loading)

using Microsoft.CodeAnalysis.Scripting.Hosting;

using (var loader = new InteractiveAssemblyLoader())
{
    var script = CSharpScript.Create<int>("1", assemblyLoader: loader);
    //do stuff 
}

参考

https://github.com/dotnet/roslyn/blob/main/docs/wiki/Scripting-API-Samples.md

作者: Niuery Daily

出处: https://www.cnblogs.com/pandefu/>

标签:脚本,await,script,C#,APIs,CSharpScript,Roslyn,var,Scripting
From: https://www.cnblogs.com/Leo_wl/p/17744203.html

相关文章

  • .net webapiSwagger启用ApiKey身份验证
     直接在SwaggerConfig中设置请求头,这里请求头用的默认值apiKey,也可以自己定义一个 privateconststringswaggerApikey="Authorization";GlobalConfiguration.Configuration.MessageHandlers.Add(newSwaggerMessageHandler());GlobalConfiguration.......
  • 使用 Docker Compose 安装 APISIX
    1.基本概念APISIX是Apache下的一款云原生的API网关,支持全生命周期的API管理,在应用中可以作为所有API调用的统一入口。APISIX有一些基础概念如下:Upstream,或者叫做上游,是一组目标主机的抽象,上游一组节点提供实际的业务服务,一般需要指定负载均衡策略去调用。Route,路由......
  • 高版本kube-apiserver删除namespace
    确认namespace下没有资源kubectlgetall-nmy-namespacekubectldeletenamespacemy-namespace调用kube-apiserverPUT接口去掉namespace中的finalizerkubectlproxy&PID=$!curl-H"Content-Type:application/json"-XPUT-d'{"apiVersion":"......
  • 三节点master修改apiserver端口
    因业务需求,需要把apiserver的6443端口改成其它端口,k8s集群是二进制部署的,有三个master节点,调整方法如下1.修改apiserver启动service中的配置查看apiserver的service文件位置systemctlstatuskube-apiserver,找到/usr/lib/systemd/system/kube-apiserver.service修改--secure-p......
  • Kubernetes 集群的优化 节点配额和内核参数调整 自动增加etcd节点 Kube APIServer 配
    一、节点配额和内核参数调整对于公有云上的Kubernetes集群,规模大了之后很容器碰到配额问题,需要提前在云平台上增大配额。这些需要增大的配额包括:虚拟机个数vCPU个数内网IP地址个数公网IP地址个数安全组条数路由表条数持久化存储大小参考gce随着node节点的增加master节点的配......
  • SAP GUI Scripting VBA Code Snippet to Detect all IDs of the UI Elements
    '-Begin-----------------------------------------------------------------OptionExplicitDimgColl()AsStringDimjAsIntegerSubGetAll(ObjAsObject)'---------------------------------------------'-'-Recursivelycalledsubro......
  • kubectl 管理 Calico APIServer
    前提1.calico使用kubernetesAPI作为数据存储。2.Calico版本要求v3.20+使用operator部署CalicoAPIServercalico-apiserver.yamlapiVersion:operator.tigera.io/v1kind:APIServermetadata:name:defaultspec:{}创建calico-apiserver资源#kubectlapply-f......
  • APISIX介绍
    APISIX是什么ApacheAPISIX是Apache软件基金会下的云原生API网关,它兼具动态、实时、高性能等特点,提供了负载均衡、动态上游、灰度发布(金丝雀发布)、服务熔断、身份认证、可观测性等丰富的流量管理功能。可以使用ApacheAPISIX来处理传统的南北向流量,也可以处理服务间的东西向流量......
  • Dubbo使用APISIX作为网关
    为什么使用网关Dubbo服务本身没有暴露HTTP接口,客户端(如:Web,APP)无法直接调用其提供的方法。而APISIX可以通过dubbo-proxy插件为Dubbo服务提供外部访问的HTTP接口,因此特别适合与Dubbo框架一起使用。在Dubbo服务架构中如何使用APISIX关于在Dubbo服务架构中使用APISIX作为接入网关,D......
  • 使用 Roslyn引擎动态编译代码
    Roslyn引擎自2014年开源至今这么久,一直没怎么了解过,虽然VS2015早就集成了它。以前老一套的动态编译方法在.NETCore中似乎不再支持了,很多方法都是未实现的。下面就介绍如何在.NETCore环境中使用Roslyn进行动态编译。话不多说,Talkischeap,showmethecode.首先是安装nuget......