千家信息网

如何开发NetCore插件

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,这篇文章主要介绍"如何开发NetCore插件",在日常操作中,相信很多人在如何开发NetCore插件问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"如何开发NetCore
千家信息网最后更新 2025年02月01日如何开发NetCore插件

这篇文章主要介绍"如何开发NetCore插件",在日常操作中,相信很多人在如何开发NetCore插件问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"如何开发NetCore插件"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

使用NetCore3.1完成框架基本开发后实际应用于项目,需要保证框架的独立性与项目的个性化, 就需要类似于下图的插件化形式将项目放入框架这个容器中启动,下面开始详细介绍实现步骤

项目dll扫描

在框架根目录创建Plugin文件夹,项目在生成后事件使用copy命令拷贝至Plugin文件夹,框架启动时会扫描该文件夹并进行ShadowCopy到PluginTemplate文件夹中

private static void ScanPlugin()        {if (!PluginFolder.Exists)            {                PluginFolder.Create();            }if (!TempPluginFolder.Exists)            {                TempPluginFolder.Create();            }            TempPluginFolder.Attributes = FileAttributes.Normal & FileAttributes.Directory;            PluginFolder.Attributes = FileAttributes.Normal & FileAttributes.Directory;//清理临时文件。foreach (var file in TempPluginFolder.GetFiles("*.dll", SearchOption.AllDirectories))            {try{                    File.SetAttributes(file.FullName, FileAttributes.Normal);                    file.Delete();                }catch (Exception e)                {throw new Exception("请检查IIS权限");                }            }//复制插件进临时文件夹。foreach (var plugin in PluginFolder.GetFiles("*.dll", SearchOption.AllDirectories))            {try{string CopyFilePath = Path.Combine(TempPluginFolder.FullName, plugin.Name);                    File.Copy(plugin.FullName, CopyFilePath, true);                    File.SetAttributes(CopyFilePath, FileAttributes.Normal);                }catch (Exception e)                {throw new Exception("请检查IIS权限");                }            }        }

项目dll加载

直接使用ApplicationParts加载AssemblyPart即可

public static void LoadPlugin()        {            ScanPlugin();            IEnumerable AssemblyList = GetPluginAssemblies();foreach (Assembly assembly in AssemblyList)            {foreach (var type in assembly.GetTypes())                {if (type.IsAssignableFrom(typeof(Controller)) && type.Name.Contains("Controller") && type.IsClass && !type.IsAbstract)                    {string Name = type.Name;//如果有自定义的路由注解if (type.IsDefined(typeof(Route), false))                        {var areaattribute = type.GetCustomAttributes(typeof(Route), false).FirstOrDefault();                            Name = ((Route)areaattribute).Name;                            Name += "Controller";                        }if (!ControllerTypeDic.ContainsKey(Name))                        {                            ControllerTypeDic.Add(Name, type);                        }                    }                }var controllerAssemblyPart = new AssemblyPart(assembly);                CloudUtil.GetBuilder().ConfigureApplicationPartManager(apm =>{                    apm.ApplicationParts.Add(controllerAssemblyPart);                });            }            CloudUtil.GetBuilder().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);            StartPluginRefreshWatch();        }

项目视图

项目的cshtml视图文件可以手动拷贝到部署的框架Views文件夹中(正式环境),也可以通过监控当前项目的Views文件夹,如果变动进行自动拷贝(开发环境)

private static void StartPluginRefreshWatch()        {            _FileSystemWatcher.Path = CloudUtil.GetContentPath() + "/Plugin";            _FileSystemWatcher.Filter = "*.dll";            _FileSystemWatcher.Changed += _FileSystemWatcher_Changed;            _FileSystemWatcher.IncludeSubdirectories = true;            _FileSystemWatcher.NotifyFilter =NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;            _FileSystemWatcher.EnableRaisingEvents = true;if (AppConfigUtil.Configuration["Frame:ViewsPublishType"]=="AutoCopy"&& !string.IsNullOrEmpty(AppConfigUtil.Configuration["Frame:ViewsVirtualPath"]) && Directory.Exists(AppConfigUtil.Configuration["Frame:ViewsVirtualPath"]))            {                FileSystemWatcher ViewsWatcher = new FileSystemWatcher();                ViewsWatcher.Path = AppConfigUtil.Configuration["Frame:ViewsVirtualPath"];                ViewsWatcher.Changed += ViewsWatcher_Changed;                ViewsWatcher.IncludeSubdirectories = true;                ViewsWatcher.NotifyFilter =NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;                ViewsWatcher.EnableRaisingEvents = true;//系统启动时整个文件夹拷贝DirectoryInfo FrameWorkViews = new DirectoryInfo(CloudUtil.GetContentPath() + "/Views");                DirectoryInfo ProjectViews = new DirectoryInfo(AppConfigUtil.Configuration["Frame:ViewsVirtualPath"]);foreach (DirectoryInfo FDir in FrameWorkViews.GetDirectories())                {foreach (DirectoryInfo PDir in ProjectViews.GetDirectories())                    {if (PDir.Name== FDir.Name)                        {                            FileUtil.DeleteDirectoryContent(FDir.FullName);                        }                    }                }                FileUtil.CopyDirectory(AppConfigUtil.Configuration["Frame:ViewsVirtualPath"],CloudUtil.GetContentPath() + "/Views", true);            }        }

项目dll热更新

监控Plugin文件夹,若有变调用IApplicationLifetime的StopApplication重启系统

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IConfiguration configuration, Microsoft.AspNetCore.Hosting.IApplicationLifetime applicationLifetime) {      CloudUtil.SetAPP(applicationLifetime); } private static void _FileSystemWatcher_Changed(object sender, FileSystemEventArgs e) {      CloudUtil.Restrat(); } public static void Restrat() {      APP.StopApplication(); }

到此,关于"如何开发NetCore插件"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0