文章转载授权级别:B
Natasha 是一个十分便捷的动态构建库,支持.NET Standard2.0 / Core3.0+ ; 比起繁杂的 IL 指令和 Expression 的众多 API , Natasha 的构建方式更加友好简洁, 基于 Natasha 可以让动态工作变得傻瓜,简单,让开发者更加专注动态代码的逻辑。 在上一篇动态查找树的文章中,我们使用算法结合 Natasha 将字典的性能提升了一倍且支持并发,在性能优化上面取得了比较显著的成效。
下面将写一些入门的操作,希望更多的开发者能参与进来,一起提升和体验 Natasha (项目地址:https://github.com/dotnetcore/Natasha);
场景1:在程序运行时,通过外面传来的字符串,创建一个委托,并且可以回收。
string input = @"return arg1+arg2;";
//先创建域再创建委托
var func = NDomain
.Create("MyDomain") //域名为MyDomain的独立域
.Func<string, string, string>(input);
var result = func("Hello"," World!");
//result: Hello World!
//卸载独立域 - 回收
func.Delete();
场景2:在程序运行时,通过字符串创建一个类/结构体/枚举/接口。
//在名为 MyDomain 的独立域内创建一个类型
var type = NDomain.Create("MyDomain").GetType(
@"public class/struct/enum/interface DomainTest1{
public string Name;
public DomainOperator Operator;
}");
//卸载独立域 - 回收
type.Delete();
场景3:测试一个复杂的应用场景。
步骤:
1、在系统域内创建一个类A,包括一个静态方法 B。
2、在 B 方法中实现 try/catch。
3、在 B 方法中调用 SqlConnection/Json.net 等依赖库操作。
4、在 B 方法中调用当前不同命名空间的类。
5、返回一个结果。
6、在独立域创建一个静态类及方法,并返回刚才创建的系统域的 A.B 方法。
var type = NClass.Create() //Create参数为空时,使用系统域
.Public
.Namespace("OperatorOverride")
.OopName("Test1") //类名为Test1
.OopBody(@"
public static string GetTest(){
try
{
System.Data.SqlClient.SqlConnection client = new System.Data.SqlClient.SqlConnection();
client.Open();
SqlCommand cmd = client.CreateCommand();
SqlDataReader read = cmd.ExecuteReader();
return ""succeed!"";
}
catch (Exception ex)
{
Test2 test = new Test2();
test.Error = new Model2.Test3();
test.Error.Name = ex.Message;
return JsonConvert.SerializeObject(test);
}}")
.GetType();
//在随机域中返回刚刚创建的方法
var func = NDomain.Random()
.Func<Func<string>>("return Test1.GetTest;")
var GetTest = func();
Console.WriteLine(GetTest());
//结果:{"Error":{"Name":"The ConnectionString property has not been initialized."}}
场景4:针对 TryHandler类 构建一个可以自定义的处理流程,我们项目的需求变更十分频繁,在需求稳定之前我们不得不进行大量的调试和试错,希望有这么一个系统能再不重启的情况下支持我们折腾。
控制约束类:
public static class TryHandler<T>
{
//获取产品
public static Func<T, Product> GetProductEntity;
//写入数据库
public static Func<Product, bool> WriteProduct;
//日志放到队列里
public static Func<bool, Product, bool> SendLogToQueue;
//这里是入口
public static Func<T, bool> Hanlder;
}
脚本扩展类:
public static class ScriptHandler
{
//使用Natasha将字符串转换为可执行代码
public static void Handler(string str)
{
var action = NDomain.Random().Action(str);
action();
}
}
准备好写在外面需要传入的脚本,这里用 txt 文件代替,如图:
如果看不清图:主要的输出是将产品序列化到 1.txt 中,并在屏幕上打印 成功或者失败。
在入口函数:
foreach (var item in files)
{
//读脚本并让其生效
ScriptHandler.Handler(File.ReadAllText(item));
}
Apple apple = new Apple();
apple.AppleId = 10;
apple.AppleName = "苹果";
TryHandler<Apple>.Hanlder(apple);
执行结果:
{"Id":10,"Name":"苹果"}
最新版 Natasha 有了什么变化:
Natasha 所有 API 将以域为首要条件,如果使用 FastMethod / FakeMethod / Oop 等 Operator 时将默认提供三种静态实例方法:Create / Random 方便用户创建域 / 使用系统域 / 使用随机域等。
Natahsha 最新版支持命名空间引用的覆盖,增加了 CS0104 / CS0234 / CS0246 等问题处理方案,在出现二义性引用时优先使用开发者传入 Using 的命名空间,针对命名空间无效的情况,Natasha 将在第一次编译时进行过滤移除并进行第二次编译,命名空间的处理对开发者尽可能透明。
https://github.com/dotnetcore
打赏一杯酒,削减三分愁。
跟着我们走,脱发包你有。
组织打赏账户为柠檬的账户,请标注「NCC」,并留下您的名字,以下地址可查看收支明细:https://github.com/dotnetcore/Home/blob/master/Statement-of-Income-and-Expense.md
OpenNCC,专注.NET技术的公众号
https://www.dotnetcore.xyz
微信ID:OpenNCC
长按左侧二维码关注
欢迎打赏组织
给予我们更多的支持