18

【C】Natasha 插件编程

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzAwNTMxMzg1MA%3D%3D&%3Bmid=2654077231&%3Bidx=3&%3Bsn=e97c5a3f26d49888553a12423bb8dd8a
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

文章转载授权级别:C

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

r6jQjuq.jpg!web

1、插件生成

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

//使用随机域

//参数传 true 将内容编译到 DLL 中

NDomain.Random(true).Action("Console.WriteLine(\"Hello World!\");");

maiANrm.png!web

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 代码中的例子 结果对比图:

M7RJBjU.png!web

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

uaAR32m.png!web

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

4、结尾

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

https://github.com/dotnetcore

打赏一杯酒,削减三分愁。

跟着我们走,脱发包你有。

MF3me2v.jpg!web

组织打赏账户为柠檬的账户,请标注「NCC」,并留下您的名字,以下地址可查看收支明细: https://github.com/dotnetcore/Home/blob/master/Statement-of-Income-and-Expense.md JfENbyB.png!web

OpenNCC ,专注.NET技术的公众号

https://www.dotnetcore.xyz

6fAZvym.png!web 微信ID:OpenNCC

YJzIr2B.png!web 长按左侧二维码关注

欢迎打赏组织

给予我们更多的支持


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK