【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 在生成插件的同时对编译代码还进行了优化。

对其他类进行对比查看,虽然反编译里软件中显示了乱码,实际上在运行时得到的结果并没有乱码, 得益于 
I
L
Spy 对 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


长按左侧二维码关注

欢迎打赏组织
给予我们更多的支持