经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » ASP.net » 查看文章
AntSK 0.2.1 版本揭秘:动态加载dll,驱动Function Call新境界!
来源:cnblogs  作者:许泽宇  时间:2024/3/18 15:05:13  对本文有异议

        在.NET的无限宇宙中,动态加载dll似乎一直是操控代码生生不息的魔杖。今天,我将与您探讨如何通过AntSK 0.2.1 版本灵活运用dll,将Function Call的强大功能插拔自如地融入项目之中,我们走入插件化开发的全新篇章。

新版本简介

        AntSK,这个曾被我们广泛探讨过的Semantic Kernel项目,这次再度带来惊喜。在早先版本我们已经见识了其实现Function Call的威力。今日,我们有幸见证其升级再进化,0.2.1 版本究竟有何过人之处?答案就是:“动态加载dll”,这一核心玄机助您将代码实现插件化,不再拘泥于单一的AntSK平台编写,带来更加灵活的扩展性。

核心编程揭秘

        要想细致品味动态加载dll的精妙,首先要解开的锁就是“约定”。AntSK要求插件明晰其身份,一段标明“AntSK”特性的代码如同通行证,使得函数得以插入AntSK的世界。

  1. public class TestFunctionImport
  2. {
  3. /// <summary>
  4. /// 获取名称
  5. /// </summary>
  6. /// <returns>返回名称</returns>
  7. [Description("AntSK")]
  8. public string GetName()
  9. {
  10. return $"""
  11. 我的名字是AntSK,
  12. 我的作者是许泽宇
  13. 我是一个AI 知识库/智能体项目
  14. """;
  15. }
  16. }

        接下来,动态加载这块宝藏怎能轻易让人得逞?我们需要通过AssemblyLoadContext这位严厉的守门人,创建一个隔离的上下文,一步步引领我们:

  1. var loadContext = new AssemblyLoadContext("AntSKLoadContext", true);
  2. public void FuncLoad(string pluginPath)
  3. {
  4. try
  5. {
  6. if (File.Exists(pluginPath))
  7. {
  8. string directory = Path.GetDirectoryName(pluginPath);
  9. string fileName = Path.GetFileName(pluginPath);
  10. var resolver = new AssemblyDependencyResolver(directory);
  11.  
  12. // Create a custom AssemblyLoadContext
  13.  
  14. loadContext.Resolving += (context, assemblyName) =>
  15. {
  16. string assemblyPath = resolver.ResolveAssemblyToPath(assemblyName);
  17. if (assemblyPath != null)
  18. {
  19. return context.LoadFromAssemblyPath(assemblyPath);
  20. }
  21. return null;
  22. };
  23. // Load your assembly
  24. Assembly pluginAssembly = loadContext.LoadFromAssemblyPath(pluginPath);
  25. }
  26. }
  27. catch (Exception ex)
  28. {
  29. Console.WriteLine(ex.Message + " ---- " + ex.StackTrace);
  30. }
  31. }

        我们是如何评判“AntSK插件”芳容?以下搜寻被特性标记的方法:

  1. publicvoid SearchMarkedMethods()
  2. {
  3. var markedMethods = new List<MethodInfo>();
  4.  
  5. _methodCache.Clear();
  6. _methodInfos.Clear();
  7.  
  8. foreach (var assembly in _assemblies)
  9. {
  10. // 从缓存中获取标记了ActionAttribute的方法
  11. foreach (var type in assembly.GetTypes())
  12. {
  13. markedMethods.AddRange(type.GetMethods().Where(m =>
  14. {
  15. DescriptionAttribute da = (DescriptionAttribute)m.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault();
  16. return da != null && da.Description == "AntSK";
  17. }));
  18. }
  19. }
  20.  
  21. //动态加载部分
  22. var loadedAssemblies = loadContext.Assemblies.ToList();
  23. foreach (var assembly in loadedAssemblies)
  24. {
  25. // 从缓存中获取标记了ActionAttribute的方法
  26. foreach (var type in assembly.GetTypes())
  27. {
  28. markedMethods.AddRange(type.GetMethods().Where(m =>
  29. {
  30. DescriptionAttribute da = (DescriptionAttribute)m.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault();
  31. return da != null && da.Description == "AntSK";
  32. }));
  33. }
  34. }
  35.  
  36. // 构建方法调用
  37. foreach (var method in markedMethods)
  38. {
  39. var key = $"{method.DeclaringType.Assembly.GetName().Name}_{method.DeclaringType.Name}_{method.Name}";
  40. string pattern = "[^a-zA-Z0-9_]";
  41. // 使用 '-' 替换非ASCII的正则表达式的字符
  42. key = Regex.Replace(key, pattern, "_");
  43. _methodCache.TryAdd(key, method);
  44.  
  45. var xmlCommentHelper = new XmlCommentHelper();
  46. xmlCommentHelper.LoadAll();
  47.  
  48. var description = xmlCommentHelper.GetMethodComment(method);
  49. var dict = xmlCommentHelper.GetParameterComments(method);
  50.  
  51. var parameters = method.GetParameters().Select(x => (x.Name, x.ParameterType, dict[x.Name])).ToArray();
  52. var returnType = xmlCommentHelper.GetMethodReturnComment(method);
  53.  
  54. if (string.IsNullOrEmpty(description))
  55. {
  56. description = "导入插件";
  57. }
  58. _methodInfos.TryAdd(key, (description, (method.ReflectedType, returnType), parameters));
  59. }
  60. }

  

技术深度解读 

        动态加载dll的涵义远不止于表面的灵活,它开辟了无需重启应用程序即可更新程序功能的可能。通过以上技巧,我们能够在代码运行时插入或移除功能模块,极大地提升了代码的模块化和可维护性。

结语

        搭上.Net技术的快车,我们仿佛有了横穿时空的能力。AntSK 0.2.1版本正是这趟快车上一颗灿烂的星子,动态加载,插件化编程,让Function Call这一古老而又强大的术语,获得了新的生命力。而今日的揭秘之旅,不知是否已让您心潮澎湃,跃跃欲试?

        别忘了,每一段代码都饱含着程序员的智慧与汗水,它们值得我们去细细玩味和传唱。如果想要了解更多.Net技术,别忘了关注我的公众号,后续还有更多精彩内容等待着你来探索。向着代码的化简难度,以及编程模块化的美好未来,我们携手同行,共同进步!

福利补充

        为了让您更好地理解AntSK的插件化魔法,公众号下期将提供详细代码教程及其运用案例,敬请期待!别让知识止步于此,让我们在共享知识的海洋中,尽情航行吧!

 

原文链接:https://www.cnblogs.com/xuzeyu/p/18077709

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号