首页 > 其他分享 >AntSK 0.2.1 版本揭秘:动态加载dll,驱动Function Call新境界!

AntSK 0.2.1 版本揭秘:动态加载dll,驱动Function Call新境界!

时间:2024-03-16 21:56:56浏览次数:18  
标签:Function 插件 string 0.2 dll AntSK var method 加载

        在.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的插件化魔法,公众号下期将提供详细代码教程及其运用案例,敬请期待!别让知识止步于此,让我们在共享知识的海洋中,尽情航行吧!

 

标签:Function,插件,string,0.2,dll,AntSK,var,method,加载
From: https://www.cnblogs.com/xuzeyu/p/18077709

相关文章

  • 启动应用程序出现cmdial32.dll找不到问题解决
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个cmdial32.dll文件(挑选合适的版本文件)把它......
  • 启动应用程序出现comcat.dll找不到问题解决
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个comcat.dll文件(挑选合适的版本文件)把它放......
  • QSVRMGMT.DLL文件丢失导致程序无法运行问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个QSVRMGMT.DLL文件(挑选合适的版本文件)把它......
  • provsvc.dll文件丢失导致程序无法运行问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个provsvc.dll文件(挑选合适的版本文件)把它放......
  • Windows7系统vdsutil.dll文件丢失问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个vdsutil.dll文件(挑选合适的版本文件)把它放......
  • 赛灵思Vivado 2020.2安装教程超详细,同样适用vivado2018版本(注意本教程仅供学习使用)
    注意本教程仅供学习使用一、软件安装二、软件免验证方式一、软件安装安装包可以到正点原子资料网站下载(达芬奇Pro开发板资料)Vivado官方建议关闭杀毒软件后安装(红色字体)关闭防火墙和杀毒软件点击next,这一页保持默认或者根据额外需要勾选同意左上角选择安装路......
  • C++ Function Templates (函数模板)
    C++FunctionTemplates[函数模板]1.TemplatesandGenericProgramming(模板与泛型编程)2.DefiningaFunctionTemplates(定义函数模板)2.1.InstantiatingaFunctionTemplate(实例化函数模板)2.2.TemplateTypeParameters(模板类型参数)2.3.Non......
  • Linux源码安装nginx1.20.2
    下面是关于Linux源码安装nginx1.20.2的操作流程目录前言1,安装准备1.1下载安装包 1.2上传安装包1.3解压  1.4关闭防火墙和selinux2,安装 nginx依赖库以及编译环境2.1安装nginx依赖库 2.2执行configure脚本生成makefile配置文件2.2.1可能出现的错误 3,......
  • MySQL 5.5和8.0.2 安装在一台电脑上
    情况说明:MySQL5.5已经安装,安装MySQL8方法一:InstallDirectory更改为C:\ProgramFiles\MySQLE\MySQLServer8.0;DataDirectory更改为C:\ProgramData\MySQLE\MySQLServer8(默认路径加E,也可以自定义)2.安装时更改端口号为3307、XProtocolPort为330703.添加环境变量path......
  • find function symbol from .a and .so in a directory
    Ihavepostedamethodtofindclasssymbolfromadirectoryinthepreviousarticle.Todayigotaquestioninfindingfunctionsysbol.Sothefellowscriptcodewascreatedtosolvethequestion.#!/bin/bashdotMaxCnt=200functionprocessLine(){ if......