2025-04-24 21:01:01 +08:00
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using Volo.Abp;
|
|
|
|
|
|
using Volo.Abp.DependencyInjection;
|
|
|
|
|
|
using Volo.Abp.Modularity;
|
|
|
|
|
|
|
|
|
|
|
|
namespace JiShe.CollectBus.DynamicModule
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 动态模块管理器的实现
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class DynamicModuleManager : IDynamicModuleManager, ISingletonDependency
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly IModuleContainer _moduleContainer;
|
|
|
|
|
|
private readonly IServiceProvider _serviceProvider;
|
|
|
|
|
|
|
|
|
|
|
|
public DynamicModuleManager(
|
|
|
|
|
|
IModuleContainer moduleContainer,
|
|
|
|
|
|
IServiceProvider serviceProvider)
|
|
|
|
|
|
{
|
|
|
|
|
|
_moduleContainer = moduleContainer;
|
|
|
|
|
|
_serviceProvider = serviceProvider;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Type[] GetRegisteredModuleTypes()
|
|
|
|
|
|
{
|
|
|
|
|
|
return _moduleContainer.Modules.Select(m => m.Type).ToArray();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async Task ReinitializeModuleAsync(Type moduleType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!typeof(IAbpModule).IsAssignableFrom(moduleType))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentException($"指定的类型 {moduleType.FullName} 不是有效的ABP模块类型", nameof(moduleType));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var moduleDescriptor = _moduleContainer.Modules.FirstOrDefault(m => m.Type.Name == moduleType.Name);
|
|
|
|
|
|
if (moduleDescriptor == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException($"找不到类型为 {moduleType.FullName} 的模块");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var module = moduleDescriptor.Instance;
|
|
|
|
|
|
|
2025-04-25 17:41:43 +08:00
|
|
|
|
await CallModuleMethodAsync(module, "OnApplicationShutdown", [new ApplicationShutdownContext(_serviceProvider)]);
|
|
|
|
|
|
var configureServicesMethod = moduleType.GetMethod("ConfigureServices",BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
|
|
|
|
|
|
if (configureServicesMethod != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var serviceConfigurationContext = CreateServiceConfigurationContext();
|
|
|
|
|
|
configureServicesMethod.Invoke(module, [serviceConfigurationContext]);
|
|
|
|
|
|
}
|
|
|
|
|
|
await CallModuleMethodAsync(module, "OnApplicationInitializationAsync", [new ApplicationInitializationContext(_serviceProvider)]);
|
2025-04-24 21:01:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async Task UnloadModuleAsync(Type moduleType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!typeof(IAbpModule).IsAssignableFrom(moduleType))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentException($"指定的类型 {moduleType.FullName} 不是有效的ABP模块类型", nameof(moduleType));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var moduleDescriptor = _moduleContainer.Modules.FirstOrDefault(m => m.Type.Name == moduleType.Name);
|
|
|
|
|
|
if (moduleDescriptor == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException($"找不到类型为 {moduleType.FullName} 的模块");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var module = moduleDescriptor.Instance;
|
|
|
|
|
|
|
|
|
|
|
|
await CallModuleMethodAsync(module, "OnApplicationShutdown", new object[] { new ApplicationShutdownContext(_serviceProvider) });
|
|
|
|
|
|
moduleDescriptor.GetType().GetProperty("IsUnloaded", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?
|
|
|
|
|
|
.SetValue(moduleDescriptor, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsModuleLoaded(Type moduleType)
|
|
|
|
|
|
{
|
|
|
|
|
|
var moduleDescriptor = _moduleContainer.Modules.FirstOrDefault(m => m.Type == moduleType);
|
|
|
|
|
|
if (moduleDescriptor == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查模块是否已被标记为卸载
|
|
|
|
|
|
var isUnloaded = (bool?)moduleDescriptor.GetType().GetProperty("IsUnloaded", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?
|
|
|
|
|
|
.GetValue(moduleDescriptor) ?? false;
|
|
|
|
|
|
|
|
|
|
|
|
return !isUnloaded;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Type GetModuleTypeByName(string moduleName)
|
|
|
|
|
|
{
|
|
|
|
|
|
return _moduleContainer.Modules
|
|
|
|
|
|
.FirstOrDefault(m => m.Type.Name == moduleName || m.Type.FullName == moduleName)?
|
|
|
|
|
|
.Type;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task CallModuleMethodAsync(IAbpModule module, string methodName, object[] parameters)
|
|
|
|
|
|
{
|
|
|
|
|
|
var method = module.GetType().GetMethod(methodName);
|
|
|
|
|
|
if (method == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (method.ReturnType == typeof(Task))
|
|
|
|
|
|
{
|
|
|
|
|
|
await (Task)method.Invoke(module, parameters);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
method.Invoke(module, parameters);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private ServiceConfigurationContext CreateServiceConfigurationContext()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 反射获取内部构造函数
|
|
|
|
|
|
var contextType = typeof(ServiceConfigurationContext);
|
|
|
|
|
|
var constructor = contextType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
|
|
if (constructor != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 创建新的服务集合并添加现有服务
|
|
|
|
|
|
var services = new ServiceCollection();
|
|
|
|
|
|
foreach (var service in ((IServiceCollection)_serviceProvider.GetService<IServiceCollection>()) ?? new ServiceCollection())
|
|
|
|
|
|
{
|
|
|
|
|
|
services.Add(service);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-25 17:41:43 +08:00
|
|
|
|
return (ServiceConfigurationContext)constructor.Invoke([services]);
|
2025-04-24 21:01:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果反射失败,使用备选方案
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
|
|
|
|
|
|
var services = new ServiceCollection();
|
|
|
|
|
|
|
|
|
|
|
|
var context = Activator.CreateInstance(contextType, bindingFlags, null, null, null);
|
|
|
|
|
|
|
|
|
|
|
|
var servicesProperty = contextType.GetProperty("Services");
|
|
|
|
|
|
servicesProperty?.SetValue(context, services);
|
|
|
|
|
|
|
|
|
|
|
|
return (ServiceConfigurationContext)context;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException("无法创建ServiceConfigurationContext。这可能是由于与ABP框架版本不兼容造成的。");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|