在.NET的無限宇宙中,動態載入dll似乎一直是操控程式碼生生不息的魔杖。今天,我將與您探討如何透過AntSK 0.2.1 版本靈活運用dll,將Function Call的強大功能插拔自如地融入專案之中,我們走入外掛化開發的全新篇章。
新版本簡介
AntSK,這個曾被我們廣泛探討過的Semantic Kernel專案,這次再度帶來驚喜。在早先版本我們已經見識了其實現Function Call的威力。今日,我們有幸見證其升級再進化,0.2.1 版本究竟有何過人之處?答案就是:“動態載入dll”,這一核心玄機助您將程式碼實現外掛化,不再拘泥於單一的AntSK平臺編寫,帶來更加靈活的擴充套件性。
核心程式設計揭秘
要想細緻品味動態載入dll的精妙,首先要解開的鎖就是“約定”。AntSK要求外掛明晰其身份,一段標明“AntSK”特性的程式碼如同通行證,使得函式得以插入AntSK的世界。
public class TestFunctionImport { /// <summary> /// 獲取名稱 /// </summary> /// <returns>返回名稱</returns> [Description("AntSK")] public string GetName() { return $""" 我的名字是AntSK, 我的作者是許澤宇 我是一個AI 知識庫/智慧體專案 """; } }
接下來,動態載入這塊寶藏怎能輕易讓人得逞?我們需要透過AssemblyLoadContext這位嚴厲的守門人,建立一個隔離的上下文,一步步引領我們:
var loadContext = new AssemblyLoadContext("AntSKLoadContext", true); public void FuncLoad(string pluginPath) { try { if (File.Exists(pluginPath)) { string directory = Path.GetDirectoryName(pluginPath); string fileName = Path.GetFileName(pluginPath); var resolver = new AssemblyDependencyResolver(directory); // Create a custom AssemblyLoadContext loadContext.Resolving += (context, assemblyName) => { string assemblyPath = resolver.ResolveAssemblyToPath(assemblyName); if (assemblyPath != null) { return context.LoadFromAssemblyPath(assemblyPath); } return null; }; // Load your assembly Assembly pluginAssembly = loadContext.LoadFromAssemblyPath(pluginPath); } } catch (Exception ex) { Console.WriteLine(ex.Message + " ---- " + ex.StackTrace); } }
我們是如何評判“AntSK外掛”芳容?以下搜尋被特性標記的方法:
publicvoid SearchMarkedMethods() { var markedMethods = new List<MethodInfo>(); _methodCache.Clear(); _methodInfos.Clear(); foreach (var assembly in _assemblies) { // 從快取中獲取標記了ActionAttribute的方法 foreach (var type in assembly.GetTypes()) { markedMethods.AddRange(type.GetMethods().Where(m => { DescriptionAttribute da = (DescriptionAttribute)m.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault(); return da != null && da.Description == "AntSK"; })); } } //動態載入部分 var loadedAssemblies = loadContext.Assemblies.ToList(); foreach (var assembly in loadedAssemblies) { // 從快取中獲取標記了ActionAttribute的方法 foreach (var type in assembly.GetTypes()) { markedMethods.AddRange(type.GetMethods().Where(m => { DescriptionAttribute da = (DescriptionAttribute)m.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault(); return da != null && da.Description == "AntSK"; })); } } // 構建方法呼叫 foreach (var method in markedMethods) { var key = $"{method.DeclaringType.Assembly.GetName().Name}_{method.DeclaringType.Name}_{method.Name}"; string pattern = "[^a-zA-Z0-9_]"; // 使用 '-' 替換非ASCII的正規表示式的字元 key = Regex.Replace(key, pattern, "_"); _methodCache.TryAdd(key, method); var xmlCommentHelper = new XmlCommentHelper(); xmlCommentHelper.LoadAll(); var description = xmlCommentHelper.GetMethodComment(method); var dict = xmlCommentHelper.GetParameterComments(method); var parameters = method.GetParameters().Select(x => (x.Name, x.ParameterType, dict[x.Name])).ToArray(); var returnType = xmlCommentHelper.GetMethodReturnComment(method); if (string.IsNullOrEmpty(description)) { description = "匯入外掛"; } _methodInfos.TryAdd(key, (description, (method.ReflectedType, returnType), parameters)); } }
技術深度解讀
動態載入dll的涵義遠不止於表面的靈活,它開闢了無需重啟應用程式即可更新程式功能的可能。透過以上技巧,我們能夠在程式碼執行時插入或移除功能模組,極大地提升了程式碼的模組化和可維護性。
結語
搭上.Net技術的快車,我們彷彿有了橫穿時空的能力。AntSK 0.2.1版本正是這趟快車上一顆燦爛的星子,動態載入,外掛化程式設計,讓Function Call這一古老而又強大的術語,獲得了新的生命力。而今日的揭秘之旅,不知是否已讓您心潮澎湃,躍躍欲試?
別忘了,每一段程式碼都飽含著程式設計師的智慧與汗水,它們值得我們去細細玩味和傳唱。如果想要了解更多.Net技術,別忘了關注我的公眾號,後續還有更多精彩內容等待著你來探索。向著程式碼的化簡難度,以及程式設計模組化的美好未來,我們攜手同行,共同進步!
福利補充
為了讓您更好地理解AntSK的外掛化魔法,公眾號下期將提供詳細程式碼教程及其運用案例,敬請期待!別讓知識止步於此,讓我們在共享知識的海洋中,盡情航行吧!