插件基础组件初步开发完成
This commit is contained in:
parent
7dc6d60897
commit
256c00cfe2
59
Falcon.SugarApi/Plugin/AssemblyLoadHelp.cs
Normal file
59
Falcon.SugarApi/Plugin/AssemblyLoadHelp.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
|
||||
namespace Falcon.SugarApi.Plugin
|
||||
{
|
||||
/// <summary>
|
||||
/// 加载程序集帮助方法
|
||||
/// </summary>
|
||||
public static class AssemblyLoadHelp
|
||||
{
|
||||
/// <summary>
|
||||
/// 加载到当前域程序集
|
||||
/// </summary>
|
||||
/// <param name="assemblyPath">程序集路径</param>
|
||||
/// <returns></returns>
|
||||
public static Assembly AssemblyLoad(string assemblyPath) {
|
||||
return Assembly.LoadFrom(assemblyPath);
|
||||
}
|
||||
/// <summary>
|
||||
/// 使用ALC加载程序集
|
||||
/// </summary>
|
||||
/// <param name="assemblyPath">程序集路径</param>
|
||||
/// <returns>程序集</returns>
|
||||
public static Assembly ALCLoad(string assemblyPath) {
|
||||
var context = new AssemblyLoadContext(assemblyPath);
|
||||
return context.LoadFromAssemblyPath(assemblyPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取程序集的加载上下文AssemblyLoadContext
|
||||
/// </summary>
|
||||
/// <param name="assembly">程序集</param>
|
||||
/// <returns>加载上下文</returns>
|
||||
public static AssemblyLoadContext? GetAssemblyLoadContext(Assembly assembly) {
|
||||
return AssemblyLoadContext.GetLoadContext(assembly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用alc加载程序集到内存,避免程序集文件被锁定
|
||||
/// </summary>
|
||||
/// <param name="assemblyPath">程序集路径</param>
|
||||
/// <returns>程序集</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 卸载alc,所有加载的程序集将一同卸载
|
||||
/// </summary>
|
||||
/// <param name="context">ALC上下文</param>
|
||||
public static void ALCUnload(AssemblyLoadContext context) {
|
||||
context.Unload();
|
||||
}
|
||||
}
|
||||
}
|
67
Falcon.SugarApi/Plugin/Client/IServiceCollectionExtend.cs
Normal file
67
Falcon.SugarApi/Plugin/Client/IServiceCollectionExtend.cs
Normal file
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务扩展 客户端调用
|
||||
/// </summary>
|
||||
public static class IServiceCollectionExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 注册当前程序集中的控制器
|
||||
/// </summary>
|
||||
/// <param name="services">服务集合</param>
|
||||
/// <returns>服务集合</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册后台背景任务
|
||||
/// </summary>
|
||||
/// <typeparam name="T">任务类型</typeparam>
|
||||
/// <param name="services">服务集合</param>
|
||||
/// <returns>服务集合</returns>
|
||||
public static IServiceCollection AddPluginsBackTask<T>(this IServiceCollection services)
|
||||
where T : BackgroundLongTask => services.AddHostedService<T>();
|
||||
|
||||
/// <summary>
|
||||
/// 注册插件配置
|
||||
/// </summary>
|
||||
/// <typeparam name="T">配置类型</typeparam>
|
||||
/// <param name="services">服务集合</param>
|
||||
/// <param name="options">配置实体</param>
|
||||
/// <returns>服务集合</returns>
|
||||
public static IServiceCollection AddPluginOption<T>(this IServiceCollection services,T options)
|
||||
where T : class => services.AddSingleton(options);
|
||||
|
||||
/// <summary>
|
||||
/// 注册插件配置
|
||||
/// </summary>
|
||||
/// <typeparam name="T">配置类型</typeparam>
|
||||
/// <param name="services">服务集合</param>
|
||||
/// <param name="config">可选,应用配置节点</param>
|
||||
/// <param name="optionBuilder">可选,配置创建器</param>
|
||||
/// <returns>服务集合</returns>
|
||||
public static IServiceCollection AddPluginOption<T>(this IServiceCollection services,IConfigurationSection? config,Action<T>? optionBuilder)
|
||||
where T : class, new() {
|
||||
var options = config == null ? new T() : config.Get<T>();
|
||||
options = options ?? throw new Exception("Get Options fail!");
|
||||
optionBuilder?.Invoke(options);
|
||||
return services.AddPluginOption(options);
|
||||
}
|
||||
}
|
||||
}
|
1
Falcon.SugarApi/Plugin/Client/Readme.md
Normal file
1
Falcon.SugarApi/Plugin/Client/Readme.md
Normal file
|
@ -0,0 +1 @@
|
|||
## 插件客户端方法
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 查找插件服务
|
||||
/// </summary>
|
||||
public static class FindPluginService
|
||||
{
|
||||
/// <summary>
|
||||
/// 查找并增加插件服务
|
||||
/// </summary>
|
||||
/// <param name="assemblyFile">程序集名称</param>
|
||||
/// <param name="services">服务集合</param>
|
||||
/// <param name="configuration">配置</param>
|
||||
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);
|
||||
}
|
||||
/// <summary>
|
||||
/// 查找并增加插件服务
|
||||
/// </summary>
|
||||
/// <param name="assembly">程序集</param>
|
||||
/// <param name="services">服务集合</param>
|
||||
/// <param name="configuration">配置</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Falcon.SugarApi.Plugin
|
||||
{
|
||||
/// <summary>
|
||||
/// 插件设置
|
||||
/// </summary>
|
||||
public class PluginSetting
|
||||
{
|
||||
/// <summary>
|
||||
/// 插件名称
|
||||
/// </summary>
|
||||
public string name { get; set; }
|
||||
/// <summary>
|
||||
/// 插件文件
|
||||
/// </summary>
|
||||
public string file { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Falcon.SugarApi.Plugin
|
||||
{
|
||||
/// <summary>
|
||||
/// 插件设置列表
|
||||
/// </summary>
|
||||
public class PluginSettingList:List<PluginSetting> { }
|
||||
}
|
80
Falcon.SugarApi/Plugin/Service/IServiceCollectionExtend.cs
Normal file
80
Falcon.SugarApi/Plugin/Service/IServiceCollectionExtend.cs
Normal file
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务扩展 服务端调用
|
||||
/// </summary>
|
||||
public static class IServiceCollectionExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 注册插件。
|
||||
/// <para>查找插件中的IServicePlugin实现,并运行其中的AddServices方法注册和初始化插件</para>
|
||||
/// </summary>
|
||||
/// <param name="services">服务集合</param>
|
||||
/// <param name="config">应用程序配置</param>
|
||||
/// <param name="pluginNames">插件名称数组</param>
|
||||
/// <returns>服务集合</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册插件中的控制器。一般由插件自行注册。
|
||||
/// </summary>
|
||||
/// <param name="services">服务集合</param>
|
||||
/// <param name="assemblyPath">插件程序集文件路径</param>
|
||||
/// <returns>服务集合</returns>
|
||||
public static IServiceCollection AddPluginsController(this IServiceCollection services,string assemblyPath) {
|
||||
var pluginAssembly = Assembly.LoadFrom(assemblyPath);
|
||||
return services.AddPluginsController(pluginAssembly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册插件中的控制器。一般由插件自行注册。
|
||||
/// </summary>
|
||||
/// <param name="services">服务集合</param>
|
||||
/// <param name="assembly">插件程序集</param>
|
||||
/// <returns>服务集合</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
1
Falcon.SugarApi/Plugin/Service/Readme.md
Normal file
1
Falcon.SugarApi/Plugin/Service/Readme.md
Normal file
|
@ -0,0 +1 @@
|
|||
## 服务端调用方法
|
Loading…
Reference in New Issue
Block a user