在.NET的無限宇宙中,動態載入dll似乎一直是操控程式碼生生不息的魔杖。今天,我將與您探討如何透過AntSK 0.2.1 版本靈活運用dll,將Function Call的強大功能插拔自如地融入計畫之中,我們走入外掛程式化開發的全新篇章。
新版本簡介
AntSK,這個曾被我們廣泛探討過的Semantic Kernel計畫,這次再度帶來驚喜。在早先版本我們已經見識了其實作Function Call的威力。今日,我們有幸見證其升級再前進演化,0.2.1 版本究竟有何過人之處?答案就是:「動態載入dll」,這一核心玄機助您將程式碼實作外掛程式化,不再拘泥於單一的AntSK平台編寫,帶來更加靈活的擴充套件性。
核心編程揭秘
要想細致品味動態載入dll的精妙,首先要解開的鎖就是「約定」。AntSK要求外掛程式明晰其身份,一段標明「AntSK」特性的程式碼如同通行證,使得函式得以插入AntSK的世界。
public classTestFunctionImport
{
/// <summary>
/// 獲取名稱
/// </summary>
/// <returns>返回名稱</returns>
[Description("AntSK")]
public string GetName()
{
return $"""
我的名字是AntSK,
我的作者是許澤宇
我是一個AI 知識庫/智慧體計畫
""";
}
}
接下來,動態載入這塊寶藏怎能輕易讓人得逞?我們需要透過 AssemblyLoadContext 這位嚴厲的守門人,建立一個隔離的上下文,一步步引領我們:
var loadContext = new AssemblyLoadContext("AntSKLoadContext", true);
publicvoid 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);
}
returnnull;
};
// 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 (vartypein 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 (vartypein 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的外掛程式化魔法,公眾號下期將提供詳細程式碼教程及其運用案例,敬請期待!別讓知識止步於此,讓我們在共享知識的海洋中,盡情航行吧!
相關文章