日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用 Natasha 写个类型调用的架子

發布時間:2023/12/4 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用 Natasha 写个类型调用的架子 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、想法

自上篇文章,我一直琢磨整個好點的例子來展示 Natasha 動態編程能力, 于是就寫了一個簡單的類型調用的架子,耗時40分鐘左右, ?項目地址:https://github.com/NMSAzulX/TypeCaller

二、功能特點

a)、簡單的注入功能

  • 支持無參構造注入

  • 支持遞歸注入

  • 保證原生性能

b)、方法映射與掃描

  • 僅掃描當前程序集

  • 掃描繼承自 BaseRpc 類的 Rpc 路由

  • 使用類名+方法名與動態委托形成映射

  • 在當前生命周期使用靜態?AOP?類包裹方法

c)、對接與調用? ??

  • 使用 params object[] 來對接調用參數

  • 使用 object 作為返回值

三、功能點解析

使用代碼預覽:

在請求達到后,Caller 根據路由執行委托,在委托中:

1、程序首先 new 了一個 RPC 實例

2、緊接著初始化實例中注入的接口

3、然后實例調用了路由中指向的方法(下文中?RPC 實例統稱為”路由“)

4、最后返回結果。

注入(初始化)實現

由于需要有遞歸的構建,因此需要 instanceName 來記錄上一次遞歸出來的對象名。而上一次構建的代碼段則放在 script 中。?

public static (StringBuilder script, string instanceName) HandlerCtor(Type type,int deepth = 0)

返回值中的 script 為初始化代碼,例如:

var?instance?=?new?XXXRpc(); instance._xxService?=?new?DefaultXXXSerivce();

由于 service 中可能還有其他 service, 因此需要遞歸下去:

第二次遞歸

var instance1 = new DefaultXXXSerivce(); instance1._xxService = new DefaultXXXSerivce2();var instance = new XXXRpc(); instance._xxService?=?instance1;??

第三次遞歸

var instance2 = new DefaultXXXService3();var instance1 = new DefaultXXXSerivce(); instance1._xxService = new DefaultXXXSerivce2(); instance1._xxService = instance2;var instance = new XXXRpc(); instance._xxService = instance1;

注意:這里我們用的初始化方法都是針對 Readonly 字段,實際上真實腳本并不是上面那樣,這里只是為了展示代碼邏輯。

這段代碼展示了初始化腳本對注入類型和非注入類型的實例化處理:

if (_injectionMapping.ContainsKey(type)) {//對注入的接口/抽象類等類型使用已實現的類型進行實例化ctorBuilder.Append($"var?{instance}?=?new?{_injectionMapping[type].GetDevelopName()}();"); }else {//對非注入類型直接?newctorBuilder.Append($"var {instance} = new {type.GetDevelopName()}();"); }

下面這段代碼遍歷了當前類的只讀字段,如果遇到了只讀字段則發生以下處理:

  • 觸發遞歸,繼續生成實例化代碼。

  • 給只讀字段賦值

foreach (var item in fields) {var result = HandlerCtor(item.FieldType, deepth);if?(result?!=?default){ctorBuilder.Insert(0, result.script);var?readonnlyFieldScript?=?$"{instance}.{item.Name}".ReadonlyScript();ctorBuilder.Append($"{readonnlyFieldScript}={result.instanceName};");} }

HelloRpc 為路由和方法的載體,繼承 BaseRpc 以便被掃描

public?class?HelloRpc?:?BaseRpc {private?readonly?IHelloServices?_helloServices;public?string?GetHello(string?name){return?_helloServices.GetHello(name);} }

下面便是對參數轉換和方法調用的處理,需要反射的技術,如果還不清楚,可以參考我們公眾號【 NCC開源社區 】癡良的反射系列文章;

NDelegate.RandomDomain(item=>?{?item.LogSyntaxError()?//如果語法構建出錯,則記錄日志?.UseFileCompile();?//將結果編譯到 DLL 文件中 }) .SetClass(item=>item.AllowPrivate(type)) .Func<object[], object>( @$" //實則這里是個 stringbuilder 來自于對參數的處理 //這里我簡化成能看懂的代碼 var?name?=?(string)arg[0];{剛才處理的初始化字符串}//?AOP?Before 調用 if(Aop<{type.GetDevelopName()}>.Before.TryGetValue(""{method.Name}"", out var beforeFunc)){{ beforeFunc(instance,arg); }}//調用?路由Rpc.Method(arg) var?result?=?instance.{method.Name}({methodParametersScript});//?AOP?After調用 if(Aop<{type.GetDevelopName()}>.After.TryGetValue(""{method.Name}"", out var afterFunc)){{ afterFunc(instance,arg); }}return?result;" );

準備 Service?

DefaultTypeService 類自己就能實例化,如果這個類你懶得在代碼里手動寫它的實例化,可以通過? FrameworkService.AddInjection<DefaultTypeService>();? 注入進去。

public class DefaultTypeService {public virtual void Show(){Console.WriteLine("Run : In TypeService! Means : Dependency injection Succeed! ");} }

DefaultHelloService?實現了 IHelloServices 抽象類或者接口,通過 FrameworkService.AddInjection<IHelloServices, DefaultHelloService>(); 注入進去。

public abstract class IHelloServices{protected readonly DefaultTypeService _typeService;public abstract string GetHello(string name);} public class DefaultHelloService : IHelloServices {public override string GetHello(string name){_typeService.Show();System.Console.WriteLine("Run : Contact 'Hello' and {Parameter}!");return "Hello " + name;} }

用 ILSpy 查看 Natasha 生成的動態映射方法:

運行:xx.exe Hello.GetHello ?"1"

四、功能擴展

上面的例子有點過于簡單,這里我從幾個角度來擴展一下,看看 Natasha 還能為它做些什么:

注入功能:

  • 無配置

  • 無區分生命周期

  • 無域隔離

  • 無熱拔管理

生命周期以及域隔離與回收,增加了編程的維度,配置可以讓注入規則更加多樣化。從生命周期的維度來講,增加該維度可以讓對象的創建與回收可控,對作用域有幫助,對提升性能和減小內存開銷有一定的好處。域隔離則更是讓插件編程放肆起來,結合域回收與創建,我們可以實現在不重啟的情況下,更換方法依賴的插件,從而改變執行結果。若使用域隔離的回收,你要搜集關于該域的所有引用,只有移除引用才能回收,從而實現熱拔?。

路由映射:

  • 無熱拔

  • 未支持插件程序集掃描

熱拔同上不細說了,插件程序集掃描可以根據開發者加載的 DLL,掃描符合 BaseRpc 的路由類型,動態編譯到路由映射字典中,實現熱插。

上下文與調用鏈:

調用鏈可以滿足中間件的需求,添加認證,靜態資源,權限校驗,監控等功能模塊,另外主鏈與旁鏈的處理也是必不可少的功能,這里參照 ASP.NET CORE 的實現即可。

五、性能優化

該示例雖然已經可以滿足高性能要求,但比起極致還遠遠不足。

注入方面

????????冪等方法注入:某些類的方法滿足冪等性,考慮是否可以使用單例對像與其進行映射,從而減少內存開銷和對象創建的時間。?

????????按需注入:雖然全網我都沒聽說過按需注入的功能,但想了一下可以實現,通過空引用異常或反編譯我們可以對映射方法進行多次優化編譯,從而達到按需注入的功能,例如:在不需要 ServiceA 的方法中,初始化代碼則不會對 _aService 字段進行賦值和初始化,可能有人會說如果你檢測不出來怎么辦,檢測不出來也不影響你使用。

????????注入對象的AOP :? 注入的對象可以通過代理方式實現 AOP ,參見下面的代理AOP.

? ? ? ??對象池:針對注入字段較多且可池化的對象,可以采用對象池進行存儲,當然了對象池用處不僅僅在這里用,其他場景也會用到。

高速分發

真正的 RPC 需要對接網絡層,在協議的約束下我們在拿到路由的時候可以以?比特數組 / 字符串等方式作為尋址依據,找到與其映射的方法并調用,高速映射實現的方式有多種,比如 .NET的并發字典,只讀并發字典,Trie 結構,我和小曾寫的查找樹變種等等。

更高效的委托執行

還在調研中,如果你已經了解該技術要點,歡迎貢獻,真的感激不盡。

強類型參數

我們例子中的參數使用了 Object 類型,拆裝箱肯定是有性能損耗,這點可以從序列化層面去解決,在路由解析完之后,把參數部分的 byte[] span 傳入動態映射的方法中,內部對其做強類型的反序列化操作,并直接傳給被調用的實例方法做參數。原來的映射方法 Func<object[], object> 變成 Func<byte[], byte[]> 這里沒打錯,你序列化進來,再序列化出去,如果你有上下文的設計,還可以自定義一些返回值,然后與尾部的序列化方法做對接。

代理AOP

例子中的 AOP 實現是用了靜態泛型類加上并發字典 ( Aop<rpc>.After["method"]()),實際上我們可以把 HelloRpc 的 AOP 進行靜態類的代理, 比如動態的創建 static class StaticAopHelloRpc ,并把 Before 及 After 方法全部換成和原函數的強類型實現 StaticAopHelloRpc.Beforexxx()?,偽代碼例如:

此時 AOP 的方法需要我們手寫代碼或者動態腳本編譯進去,可以用我的 RuntimeToDynamic 庫,R2D庫可以讓運行時的數據壓入到動態域中,可以放在靜態類、也可以放在普通類中等待調用,而且是強類型。(其實我原本沒想把這個庫推出來,但實在想不到有比這個更直接的方法了, 這只是一個建議,希望老友們有更好的方法)

代理類合并

代理類合并,?我們可能在動態構建的過程中產生很多的類,這些類在后期可以被整合與優化,減少調用路徑。該優化可以先期考慮進去,這關系到你動態構建的一個習慣,如果你的邏輯不是那么強,也可以放在后期去做優化。

選其他組件

如果以上都完成了,性能就優化得差不多了,下面選一些組件,初步打通遠程調用:

通信組件:?老江的 SuperSocket 高性能易用,內置了加密和協議解析等。

序列化組件:牛逼哥的 Swifter.Json 。

就此一個模棱兩可的 RPC 就差不多能跑了,后續根據反饋或者需求逐一進行優化,使用 Natasha 對請求、調用、返回整個流程進行動態化管理是一件很刺激的事情,甚至需要持久化的支持。當然了 Natasha 還有很多別的用處,比如對象映射,ORM,奇奇怪怪的調用?等等,Natasha 屬于 “正向編程” , 即便你沒有看相關的源碼,也可能寫出滿足你需求的框架。

六、鳴謝

Natasha 能做到以上那么多離不開黑科技的加持。

感謝 ”天天向上卡索“, 提供了?禁斷低版本程序集?的編譯標識,借此我開放了 Roslyn 未開放的一些標識與方法,卡索老鐵為人低調謙和,名下還有很多有趣的項目,大家多多支持。

感謝 ”牛逼哥“, Readonly 初始化后賦值的方法和委托執行性能提升的信息是由他提供的。?這里我想多說幾嘴,此人及其恐怖,6月份拿 Emit 實現的查找算法硬剛我的動態高速緩存,雖然不知道他寫了多少代碼,但我知道 Natasha 輸了1項,就很恐怖,我們群里也有說,Json.net 作者”遭遇“了日本的卡哇伊,日本的卡哇伊”遭遇“了中國的牛逼哥。在看到?Swifter?性能測試結果時真的為他高興一把,力壓群雄,干得漂亮。

七、開源生態

很多情況下性能,易用性,穩定性是一起進步的,因為我們沒能做到極致,這時候跟別的語言比反而顯得有點急功近利。后浪們要多關注技術,多實踐,別總做伸手黨,就這些框架分分鐘不就支棱起來么。有一部分大佬也是,愿意站在山頭磨磨唧唧講故事,車轱轆話轉來轉去不挑干貨講,在不就是上來否定這個否定那個,在弱勢生態里,都是弱逼,別做生態的局外人,不能置身事外。

反觀一下今年上半年,開源項目多起來了,質量也在慢慢提高,不得不說,部分國產庫做的要比國外的強得多,這是個很好的趨勢!老鐵們,每天拿出一點時間來給技術,路上多積累一些靈感,該支棱就得支棱起來,相信自己,能行啊!??

如果奇跡有顏色,那一定是中國紅!


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

長按左側二維碼關注

歡迎打賞組織

給予我們更多的支持

總結

以上是生活随笔為你收集整理的用 Natasha 写个类型调用的架子的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 天天干天天色天天射 | 五月天中文字幕 | 久久久高清免费视频 | 在线国产一区 | 国产在线不卡一区 | 日本japanese极品少妇 | 性开放耄耋老妇hd | 欧美成人一区二区三区 | 日产精品久久久一区二区 | 久久国产二区 | 日本变态折磨凌虐bdsm在线 | www.色播.com| 国产综合视频一区二区 | 91精品国产综合久久久久久久 | 欧美少妇诱惑 | 成人亚洲一区二区 | 亚洲2022国产成人精品无码区 | 中国女人毛片 | 精品99久久久久成人网站免费 | 欧美射射 | 偷偷久久 | 很嫩很紧直喷白浆h | 久久av综合 | 91精品国产综合久久精品图片 | 天天躁日日躁aaaxxⅹ | 日本在线第一页 | 国产激情影院 | 91精品久久久久久综合五月天 | 成人做受视频试看60秒 | 蜜桃av鲁一鲁一鲁一鲁俄罗斯的 | 波多野结衣潜藏淫欲 | 久久精品无码中文字幕 | 上海毛片| 国产精品97 | 自拍偷拍激情小说 | 国产a v一区二区三区 | 亚洲无av在线中文字幕 | 天天插日日干 | 亚洲综合影院 | 少妇紧身牛仔裤裤啪啪 | 国产中文欧美日韩在线 | 老司机精品福利视频 | 51精品国产人成在线观看 | 国产a级一级片 | av在线片| 天天干中文字幕 | 欧美呦呦 | 久热在线视频 | 成人激情视频在线播放 | 91视频国产一区 | 波多野结衣在线一区 | 国产777| 国产一区高清 | 欧美日韩乱国产 | 日韩精品1区2区 | 日韩av中字 | 舐丝袜脚视频丨vk | 99精品热视频 | 欧美在线日韩在线 | 人人草人人看 | 亚洲av无码乱码在线观看性色 | 短裙公车被强好爽h吃奶视频 | 日产av在线播放 | 一区二区三区日韩精品 | 中文字幕在线视频观看 | 亚洲精品视屏 | 欧美日韩一二三四区 | 91精品国产高清一区二区三密臀 | 国产精品九九视频 | 欧美粗暴jizz性欧美20 | 999精品在线视频 | 久久久久久亚洲中文字幕无码 | 精品自拍av | 91视频国产免费 | 国产精品igao | 夜色快播 | 国产精品二区在线 | 天天噜天天干 | 日本黄色大片免费 | 色吧综合网 | 日韩一区网站 | 91天天干 | 96精品国产| 亚洲 小说区 图片区 都市 | 日韩欧美一二三 | 怡红院一区二区三区 | 免费在线日韩 | 黄色片的网站 | 好吊视频一二三区 | 少妇太爽了在线观看 | 日本熟女一区二区 | 日本国产一区二区 | 国产自在线 | 亚洲一区视频在线播放 | 久久久久久国产精品日本 | 激情五月婷婷在线 | 青青草免费在线 | 欧美精品在线第一页 | 草草影院欧美 |