【C】Natasha 插件编程

文章转载授权级别:C

Natasha 是一个代替 Emit / Expression 的动态构建项目,旨在为开发者提供方便、快捷、高性能的动态构建服务,动态编程是生态的重要组成部分,希望开发者们能有足够的兴趣来了解、使用、建设它。

1、插件生成

使用 Natasha 进行动态编译并生成 dll 和 pdb 文件;

//使用随机域 
//参数传 true 将内容编译到 DLL 中
NDomain.Random(true).Action("Console.WriteLine(\"Hello World!\");");

2、插件加载

前提插件结构:

Plugin 引用了 Dependency.dll 和 MySql.Data.dll

.NET Core 2.x 使用 Natasha 加载插件,建议手动添加依赖。

var domain = DomainManagement.Random;
domain.LoadStream("Plugin.dll");
domain.LoadStream("Dependency.dll");
domain.LoadStream("MySql.Data.dll");


NDomain.Create(domain).Action("xxxx");

.NET Core3.x 官方在 core3.x 后提供了 AssemblyDependencyResolver 操作类来解析 deps.json 依赖配置文件,因此不需要再一个一个的添加了。

AssemblyDependencyResolver 操作类仅对外提供两个解析路径的方法,若需要获取引用文件的路径,需要反射私有字段。

var domain = DomainManagement.Random;
domain.LoadStream("Plugin.dll");


NDomain.Create(domain).Action("xxxx");

 

 

3、运行时动态修改插件

在群里小伙伴的建议下,开了一个动态修改插件的项目:https://github.com/night-moon-studio/DynamicPlugin ,结合 Natasha 出色的正编译及插件功能 和 ILSpy 超强的反编译功能,我们允许一个插件在运行时加载之后进行部分修改并重新编译。

场景:前提插件 Plugin 包含有 A \ B \ C 三个类, 需求是在不改变类 A \ B 的情况下,修改 C 的代码并重新生成插件,中间不能关闭程序。

//当插件使用deps.json依赖文件时
ReWriter reWriter = new ReWriter(dllPath);
reWriter["C"] = "using xxxx; namespace xxx{public class C{ ...... }}";
reWriter.Complier();
reWriter.Dispose();
return reWriter.NewDllPath;
//当插件不适用deps.json文件,且所有依赖文件都在同一目录时
ReWriter reWriter = new ReWriter(dllPath,false);
//添加额外引用DLL
reWriter.References.Add("MySql.Data.dll");
reWriter.References.Add("xxxx.dll");
reWriter["C"] = "using xxxx; namespace xxx{public class C{ ...... }}";
reWriter.Complier();
reWriter.Dispose();
return reWriter.NewDllPath;

Github 代码中的例子结果对比图:

对新旧 dll 反编译查看(下为新),可以发现 Natasha 在生成插件的同时对编译代码还进行了优化。

对其他类进行对比查看,虽然反编译里软件中显示了乱码,实际上在运行时得到的结果并没有乱码,得益于 ILSpy 对 dynamic 的反解。

4、结尾

不太会说废话,但唐突的结束不是很好,希望大家能多多吐槽我们的项目,多提建议,如果没什么问题就去干吧,干就完了.


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

长按左侧二维码关注

欢迎打赏组织

给予我们更多的支持

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值