183 lines
7.4 KiB
C#

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.Logging;
using Volo.Abp.Modularity;
using Volo.Abp.Modularity.PlugIns;
namespace JiShe.CollectBus.DynamicModule
{
/// <summary>
/// 动态模块管理器的实现
/// </summary>
public class DynamicModuleManager : IDynamicModuleManager, ISingletonDependency
{
private readonly IModuleContainer _moduleContainer;
private readonly IServiceProvider _serviceProvider;
//private readonly IModuleLoader _moduleLoader;
//private readonly IAbpApplicationWithInternalServiceProvider _abpApplicationWithInternalServiceProvider;
//private readonly IServiceCollection _services;
public DynamicModuleManager(
IModuleContainer moduleContainer,
IServiceProvider serviceProvider
//IModuleLoader moduleLoader,
//IServiceCollection services, IAbpApplicationWithInternalServiceProvider abpApplicationWithInternalServiceProvider
)
{
_moduleContainer = moduleContainer;
_serviceProvider = serviceProvider;
//_moduleLoader = moduleLoader;
//_services = services;
//_abpApplicationWithInternalServiceProvider= abpApplicationWithInternalServiceProvider;
}
public Type[] GetRegisteredModuleTypes()
{
return _moduleContainer.Modules.Select(m => m.Type).ToArray();
}
public async Task LoadModuleAsync(Type moduleType)
{
if (!typeof(IAbpModule).IsAssignableFrom(moduleType))
{
throw new ArgumentException($"指定的类型 {moduleType.FullName} 不是有效的ABP模块类型", nameof(moduleType));
}
//var modules = _moduleLoader.LoadModules(_services, moduleType, new PlugInSourceList());
using (var application = AbpApplicationFactory.Create(moduleType))
{
await application.InitializeAsync();
}
//await _abpApplicationWithInternalServiceProvider.InitializeAsync();
}
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;
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)]);
}
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);
}
return (ServiceConfigurationContext)constructor.Invoke([services]);
}
// 如果反射失败,使用备选方案
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框架版本不兼容造成的。");
}
}
}
}