运行C#脚本的解决方案,有Roslyn和Mono。CS-Script主要是基于Roslyn封装实现的,并且提供了一些额外功能:
CS-Script功能相关概念:
CS-Script官网:https://github.com/oleg-shilo/cs-script
Install-Package CS-Script
CS-Script实际上底层支持Mono/Roslyn/CodeDom三种脚本引擎,由于.NET CORE的特殊性,CS-Script.Core做了删减,只能支持Roslyn一种引擎了,支持的C#语言版本由Roslyn版本决定。
编译方法,并返回动态生成的程序集,方法被默认加载到DynamicClass类中,该Type完全限定名称为css_root+DynamicClass
,定义的静态方法需要使用以下方式调用。
//1.-------------------------------编译方法:执行cs程序-------------------------------
Assembly compilemethod = CSScript.RoslynEvaluator.CompileMethod(
@"using System;
public static void CompileMethod(string greeting)
{
Console.WriteLine(""CompileMethod:"" + greeting);
}");
var p = compilemethod.GetType("css_root+DynamicClass");
var me = p.GetMethod("CompileMethod");
me.Invoke(null, new object[] { "1" });
加载方法,并返回默认类(DynamicClass)的一个对象,通过定义返回对象为dynamic类型,可以直接调用实例方法。
//2.-------------------------------加载方法:执行cs程序-------------------------------
//eval = CSScript.Evaluator.ReferenceAssembly(sqr);
dynamic loadmethod = CSScript.Evaluator.LoadMethod(
@"using System;
public void LoadMethod(string greeting)
{
Console.WriteLine(""LoadMethod:"" +greeting);
}");
loadmethod.LoadMethod("Hello World!");
加载类,并返回代码段中的第一个类的实例,通过定义返回对象为dynamic类型,可以直接调用实例方法。
//3.-------------------------------加载类:方法执行cs程序-------------------------------
dynamic loadcode = CSScript.Evaluator
.LoadCode(@"using System;
using System.Text;
public class ScriptCC
{
public void LoadCode(string greeting)
{
Console.WriteLine(""LoadCode:"" + greeting);
}
}");
loadcode.LoadCode("111");
编译类,并返回动态生成的程序集,定义的实例方法可以使用以下方式调用。
//4.-------------------------------编译类:方法执行cs程序-------------------------------
var eval = CSScript.Evaluator.ReferenceDomainAssemblies(DomainAssemblies.AllStaticNonGAC);
var ass = eval
.CompileCode(@"using System;
public static class ScriptCCStatic
{
public static void LoadCodeStatic(string greeting)
{
Console.WriteLine(""LoadCodeStatic:"" + greeting);
}
}");
var p1 = ass.GetType("css_root+ScriptCCStatic");
var me1 = p1.GetMethod("LoadCodeStatic");
me1.Invoke(null, new object[] { "1" });
//6.-------------------------------生成实例:方法执行cs程序-------------------------------
Assembly compilecode = eval
.CompileCode(@"using System;
using System.Text;
public class ScriptLC
{
public void CompileCode(string greeting)
{
Console.WriteLine(""CompileCode:"" + greeting + Encoding.ASCII.IsBrowserDisplay);
}
}");
var ps = compilecode.GetType("css_root+ScriptLC");
var obj = compilecode.CreateInstance("css_root+ScriptLC");
var mes = ps.GetMethod("CompileCode");
mes.Invoke(obj, new object[] { "1" });
Console.WriteLine();
生成一个委托,同样定义在DynamicClass中,可以直接调用。
//5.-------------------------------生成委托:方法执行cs程序-------------------------------
var tp = eval.CreateDelegate(@"int Sqr(int a)
{
return a * a;
}");
Console.WriteLine(tp(3));
//---------------------------------------查看evaluator的引用程序集-------------------------
var ww = eval.GetReferencedAssemblies();
foreach (var n in ww)
{
if (n.GetName().Name.Contains("System")) continue;
if (n.GetName().Name.Contains("Microsoft")) continue;
if (n.GetName().Name.Contains("CS")) continue;
Console.WriteLine("AseemblyName: " + n.GetName());
foreach (var wn in n.GetTypes())
{
Console.WriteLine("Types: " + wn.Name);
}
}
Console.WriteLine();
//--------------------------------------查看当前AppDomain加载的程序集-----------------------
foreach (var n in AppDomain.CurrentDomain.GetAssemblies())
{
if (n.GetName().Name.Contains("System")) continue;
if (n.GetName().Name.Contains("Microsoft")) continue;
if (n.GetName().Name.Contains("CS")) continue;
Console.WriteLine("AseemblyName: " + n.GetName());
foreach (var wn in n.GetTypes())
{
Console.WriteLine("Types: " + wn.Name);
}
}
Console.ReadKey();