From 256c00cfe2702fdb4c490c6bc78af86afd10e117 Mon Sep 17 00:00:00 2001
From: FalconFly <12919280+falconfly@user.noreply.gitee.com>
Date: Thu, 16 Nov 2023 11:04:22 +0800
Subject: [PATCH] =?UTF-8?q?=E6=8F=92=E4=BB=B6=E5=9F=BA=E7=A1=80=E7=BB=84?=
=?UTF-8?q?=E4=BB=B6=E5=88=9D=E6=AD=A5=E5=BC=80=E5=8F=91=E5=AE=8C=E6=88=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Falcon.SugarApi/Plugin/AssemblyLoadHelp.cs | 59 ++++++++++++++
.../Plugin/Client/IServiceCollectionExtend.cs | 67 ++++++++++++++++
Falcon.SugarApi/Plugin/Client/Readme.md | 1 +
Falcon.SugarApi/Plugin/FindPluginService.cs | 63 ---------------
Falcon.SugarApi/Plugin/PluginSetting.cs | 19 -----
Falcon.SugarApi/Plugin/PluginSettingList.cs | 9 ---
.../Service/IServiceCollectionExtend.cs | 80 +++++++++++++++++++
Falcon.SugarApi/Plugin/Service/Readme.md | 1 +
8 files changed, 208 insertions(+), 91 deletions(-)
create mode 100644 Falcon.SugarApi/Plugin/AssemblyLoadHelp.cs
create mode 100644 Falcon.SugarApi/Plugin/Client/IServiceCollectionExtend.cs
create mode 100644 Falcon.SugarApi/Plugin/Client/Readme.md
delete mode 100644 Falcon.SugarApi/Plugin/FindPluginService.cs
delete mode 100644 Falcon.SugarApi/Plugin/PluginSetting.cs
delete mode 100644 Falcon.SugarApi/Plugin/PluginSettingList.cs
create mode 100644 Falcon.SugarApi/Plugin/Service/IServiceCollectionExtend.cs
create mode 100644 Falcon.SugarApi/Plugin/Service/Readme.md
diff --git a/Falcon.SugarApi/Plugin/AssemblyLoadHelp.cs b/Falcon.SugarApi/Plugin/AssemblyLoadHelp.cs
new file mode 100644
index 0000000..7962033
--- /dev/null
+++ b/Falcon.SugarApi/Plugin/AssemblyLoadHelp.cs
@@ -0,0 +1,59 @@
+using System.IO;
+using System.Reflection;
+using System.Runtime.Loader;
+
+namespace Falcon.SugarApi.Plugin
+{
+ ///
+ /// 加载程序集帮助方法
+ ///
+ public static class AssemblyLoadHelp
+ {
+ ///
+ /// 加载到当前域程序集
+ ///
+ /// 程序集路径
+ ///
+ public static Assembly AssemblyLoad(string assemblyPath) {
+ return Assembly.LoadFrom(assemblyPath);
+ }
+ ///
+ /// 使用ALC加载程序集
+ ///
+ /// 程序集路径
+ /// 程序集
+ public static Assembly ALCLoad(string assemblyPath) {
+ var context = new AssemblyLoadContext(assemblyPath);
+ return context.LoadFromAssemblyPath(assemblyPath);
+ }
+
+ ///
+ /// 获取程序集的加载上下文AssemblyLoadContext
+ ///
+ /// 程序集
+ /// 加载上下文
+ public static AssemblyLoadContext? GetAssemblyLoadContext(Assembly assembly) {
+ return AssemblyLoadContext.GetLoadContext(assembly);
+ }
+
+ ///
+ /// 使用alc加载程序集到内存,避免程序集文件被锁定
+ ///
+ /// 程序集路径
+ /// 程序集
+ public static Assembly ALCLoadInMemory(string assemblyPath) {
+ var bys = File.ReadAllBytes(assemblyPath);
+ var stream = new MemoryStream(bys);
+ var alc = new AssemblyLoadContext(assemblyPath);
+ return alc.LoadFromStream(stream);
+ }
+
+ ///
+ /// 卸载alc,所有加载的程序集将一同卸载
+ ///
+ /// ALC上下文
+ public static void ALCUnload(AssemblyLoadContext context) {
+ context.Unload();
+ }
+ }
+}
diff --git a/Falcon.SugarApi/Plugin/Client/IServiceCollectionExtend.cs b/Falcon.SugarApi/Plugin/Client/IServiceCollectionExtend.cs
new file mode 100644
index 0000000..81a3b85
--- /dev/null
+++ b/Falcon.SugarApi/Plugin/Client/IServiceCollectionExtend.cs
@@ -0,0 +1,67 @@
+using Falcon.SugarApi.BackTask;
+using Microsoft.AspNetCore.Mvc.ApplicationParts;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+namespace Falcon.SugarApi.Plugin.Client
+{
+ ///
+ /// 服务扩展 客户端调用
+ ///
+ public static class IServiceCollectionExtend
+ {
+ ///
+ /// 注册当前程序集中的控制器
+ ///
+ /// 服务集合
+ /// 服务集合
+ public static IServiceCollection AddPluginsController(this IServiceCollection services) {
+ var pluginAssembly = Assembly.GetExecutingAssembly();
+ var part = new AssemblyPart(pluginAssembly);
+ services.AddControllers().ConfigureApplicationPartManager(apm => {
+ if(!apm.ApplicationParts.Contains(part)) {
+ apm.ApplicationParts.Add(part);
+ }
+ });
+ return services;
+ }
+
+ ///
+ /// 注册后台背景任务
+ ///
+ /// 任务类型
+ /// 服务集合
+ /// 服务集合
+ public static IServiceCollection AddPluginsBackTask(this IServiceCollection services)
+ where T : BackgroundLongTask => services.AddHostedService();
+
+ ///
+ /// 注册插件配置
+ ///
+ /// 配置类型
+ /// 服务集合
+ /// 配置实体
+ /// 服务集合
+ public static IServiceCollection AddPluginOption(this IServiceCollection services,T options)
+ where T : class => services.AddSingleton(options);
+
+ ///
+ /// 注册插件配置
+ ///
+ /// 配置类型
+ /// 服务集合
+ /// 可选,应用配置节点
+ /// 可选,配置创建器
+ /// 服务集合
+ public static IServiceCollection AddPluginOption(this IServiceCollection services,IConfigurationSection? config,Action? optionBuilder)
+ where T : class, new() {
+ var options = config == null ? new T() : config.Get();
+ options = options ?? throw new Exception("Get Options fail!");
+ optionBuilder?.Invoke(options);
+ return services.AddPluginOption(options);
+ }
+ }
+}
diff --git a/Falcon.SugarApi/Plugin/Client/Readme.md b/Falcon.SugarApi/Plugin/Client/Readme.md
new file mode 100644
index 0000000..7749c95
--- /dev/null
+++ b/Falcon.SugarApi/Plugin/Client/Readme.md
@@ -0,0 +1 @@
+## ͻ˷
\ No newline at end of file
diff --git a/Falcon.SugarApi/Plugin/FindPluginService.cs b/Falcon.SugarApi/Plugin/FindPluginService.cs
deleted file mode 100644
index 5c84167..0000000
--- a/Falcon.SugarApi/Plugin/FindPluginService.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.IO;
-using System.Reflection;
-using System.Runtime.Loader;
-
-namespace Falcon.SugarApi.Plugin
-{
- ///
- /// 查找插件服务
- ///
- public static class FindPluginService
- {
- ///
- /// 查找并增加插件服务
- ///
- /// 程序集名称
- /// 服务集合
- /// 配置
- public static void FindAddPluginService(string assemblyFile,IServiceCollection services,IConfiguration configuration) {
- if(!File.Exists(assemblyFile)) {
- throw new FileNotFoundException($"插件文件没有找到:{assemblyFile}");
- }
- //var doMain = AppDomain.CurrentDomain;
- //var assembly = doMain.Load(assemblyFile);
-
- var dm = new AssemblyLoadContext(null,false);
- var assembly = dm.LoadFromAssemblyPath(assemblyFile);
-
- FindAddPluginService(assembly,services,configuration);
- }
- ///
- /// 查找并增加插件服务
- ///
- /// 程序集
- /// 服务集合
- /// 配置
- public static void FindAddPluginService(Assembly assembly,IServiceCollection services,IConfiguration configuration) {
- var name = typeof(IServicePlugin).FullName;
- if(name == null) {
- return;
- }
- foreach(Type type in assembly.GetTypes()) {
- if(type == null || !type.IsPublic) {
- continue;
- }
- if(type.GetInterface(name) == null) {
- continue;
- }
- var tname = type.FullName;
- if(tname == null) {
- continue;
- }
- var obj = type.Assembly.CreateInstance(tname) as IServicePlugin;
- if(obj == null) {
- continue;
- }
- obj.AddServices(services,configuration);
- }
- }
- }
-}
diff --git a/Falcon.SugarApi/Plugin/PluginSetting.cs b/Falcon.SugarApi/Plugin/PluginSetting.cs
deleted file mode 100644
index 345b8ce..0000000
--- a/Falcon.SugarApi/Plugin/PluginSetting.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.Collections.Generic;
-
-namespace Falcon.SugarApi.Plugin
-{
- ///
- /// 插件设置
- ///
- public class PluginSetting
- {
- ///
- /// 插件名称
- ///
- public string name { get; set; }
- ///
- /// 插件文件
- ///
- public string file { get; set; }
- }
-}
diff --git a/Falcon.SugarApi/Plugin/PluginSettingList.cs b/Falcon.SugarApi/Plugin/PluginSettingList.cs
deleted file mode 100644
index 4976003..0000000
--- a/Falcon.SugarApi/Plugin/PluginSettingList.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Collections.Generic;
-
-namespace Falcon.SugarApi.Plugin
-{
- ///
- /// 插件设置列表
- ///
- public class PluginSettingList:List { }
-}
diff --git a/Falcon.SugarApi/Plugin/Service/IServiceCollectionExtend.cs b/Falcon.SugarApi/Plugin/Service/IServiceCollectionExtend.cs
new file mode 100644
index 0000000..cfafb95
--- /dev/null
+++ b/Falcon.SugarApi/Plugin/Service/IServiceCollectionExtend.cs
@@ -0,0 +1,80 @@
+using Microsoft.AspNetCore.Mvc.ApplicationParts;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Falcon.SugarApi.Plugin.Service
+{
+ ///
+ /// 服务扩展 服务端调用
+ ///
+ public static class IServiceCollectionExtend
+ {
+ ///
+ /// 注册插件。
+ /// 查找插件中的IServicePlugin实现,并运行其中的AddServices方法注册和初始化插件
+ ///
+ /// 服务集合
+ /// 应用程序配置
+ /// 插件名称数组
+ /// 服务集合
+ public static IServiceCollection AddPluginService(this IServiceCollection services,IConfiguration config,params string[] pluginNames) {
+ var name = typeof(IServicePlugin).FullName;
+ if(name == null) {
+ return services;
+ }
+ foreach(var pluginName in pluginNames) {
+ var pa = AssemblyLoadHelp.ALCLoad(pluginName);
+ foreach(Type type in pa.GetTypes()) {
+ if(type == null || !type.IsPublic || type.GetInterface(name) == null) {
+ continue;
+ }
+ var tname = type.FullName;
+ if(tname == null) {
+ continue;
+ }
+ if(type.Assembly.CreateInstance(tname) is not IServicePlugin obj) {
+ continue;
+ }
+ obj.AddServices(services,config);
+ }
+
+ }
+ return services;
+ }
+
+ ///
+ /// 注册插件中的控制器。一般由插件自行注册。
+ ///
+ /// 服务集合
+ /// 插件程序集文件路径
+ /// 服务集合
+ public static IServiceCollection AddPluginsController(this IServiceCollection services,string assemblyPath) {
+ var pluginAssembly = Assembly.LoadFrom(assemblyPath);
+ return services.AddPluginsController(pluginAssembly);
+ }
+
+ ///
+ /// 注册插件中的控制器。一般由插件自行注册。
+ ///
+ /// 服务集合
+ /// 插件程序集
+ /// 服务集合
+ public static IServiceCollection AddPluginsController(this IServiceCollection services,Assembly assembly) {
+ var part = new AssemblyPart(assembly);
+ services.AddControllers().ConfigureApplicationPartManager(apm => {
+ if(!apm.ApplicationParts.Contains(part)) {
+ apm.ApplicationParts.Add(part);
+ }
+ });
+ return services;
+ }
+
+ }
+}
diff --git a/Falcon.SugarApi/Plugin/Service/Readme.md b/Falcon.SugarApi/Plugin/Service/Readme.md
new file mode 100644
index 0000000..2bea63b
--- /dev/null
+++ b/Falcon.SugarApi/Plugin/Service/Readme.md
@@ -0,0 +1 @@
+## ˵÷
\ No newline at end of file