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 { /// /// 动态模块管理器的实现 /// 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; 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()) ?? 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框架版本不兼容造成的。"); } } } }