using PCC2.AssemblyInject.Interfaces; namespace PCC2.AssemblyInject.Services; internal class AssemblyInjectStartStopWorker : IHostedService { private readonly ILogger> _logger; private readonly IReadOnlyCollection _syncServices; private readonly IReadOnlyCollection _asyncServices; public AssemblyInjectStartStopWorker( IServiceProvider serviceProvider, ILogger> logger) { _logger = logger; _logger.LogInformation("Activating Singleton Component..."); //单例组件 var serviceTypes = new HashSet(); foreach (var svcType in typeof(T).Assembly.GetTypes() .Where(typeof(IAssemblyInjectSingleton).IsAssignableFrom) .Where(p => p.IsInterface == false && p.IsAbstract == false) .OrderBy(p => p.Name)) { var gsi = svcType.GetInterfaces().Where(p => p.IsGenericType && p.GetGenericTypeDefinition() == typeof(IAssemblyInjectSingleton<>)).ToArray(); foreach (var type in gsi) { var addAs = type.GetGenericArguments().First(); serviceTypes.Add(addAs); } } foreach (var serviceType in serviceTypes) { var services = serviceProvider.GetServices(serviceType).ToArray(); for (var i = 0; i < services.Length; i++) { var service = services[i]; if (service != null) _logger.LogInformation($"Singleton Component Active {service.GetType().FullName}"); else logger.LogWarning($"Encounter null in Active {serviceType.FullName}#{i}"); } } foreach (var type in typeof(T).Assembly.GetTypes() .Where(type => typeof(IAssemblyInjectSingleton).IsAssignableFrom(type) && !typeof(IAssemblyInjectSingleton<>).IsAssignableFrom(type)) .Where(p => p.IsInterface == false && p.IsAbstract == false) .OrderBy(p => p.Name)) { var service = serviceProvider.GetService(type); if (service != null) { _logger.LogInformation($"Singleton Component Active {service.GetType().FullName}"); } } _syncServices = typeof(T).Assembly.GetTypes() .Where(typeof(IAssemblyInjectSyncInitStarStop).IsAssignableFrom) .Where(p => p.IsInterface == false && p.IsAbstract == false) .OrderBy(p => p.Name) .SelectMany(p => { var gsi = p.GetInterfaces().Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IAssemblyInjectSyncInitStarStop<>)).ToArray(); return gsi.Length == 0 ? [p] : gsi.Select(gi => gi.GetGenericArguments().First()); }) .Distinct() .Select(type => (type, serviceProvider.GetService(type))) .Where(p => { if (p.Item2 == null) { logger.LogWarning($"Encounter null in IAssemblyInjectSyncInitStarStop: {p.type.FullName}"); return false; } return true; }).Select(p => p.Item2) .Cast() .ToArray(); _asyncServices = typeof(T).Assembly.GetTypes() .Where(typeof(IAssemblyInjectASyncInitStarStop).IsAssignableFrom) .Where(p => p.IsInterface == false && p.IsAbstract == false) .OrderBy(p => p.Name) .SelectMany(p => { var gsi = p.GetInterfaces().Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IAssemblyInjectASyncInitStarStop<>)).ToArray(); return gsi.Length == 0 ? [p] : gsi.Select(gi => gi.GetGenericArguments().First()); }) .Distinct() .Select(type => (type, serviceProvider.GetService(type))) .Where(p => { if (p.Item2 == null) { logger.LogWarning($"Encounter null in IAssemblyInjectASyncInitStarStop: {p.type.FullName}"); return false; } return true; }).Select(p => p.Item2) .Cast() .ToArray(); } public async Task StartAsync(CancellationToken cancellationToken) { _logger.LogInformation($"Initialization..."); if (_syncServices.Count == 0) _logger.LogInformation($"No component found for sync init."); else { foreach (var service in _syncServices) { _logger.LogInformation($"Initializing sync {service.GetType()}"); try { service.Init(); } catch (Exception e) { _logger.LogError(e, nameof(service.Init)); } } _logger.LogInformation($"All components sync initialized."); } if (_asyncServices.Count == 0) _logger.LogInformation($"No component found for async init."); else { foreach (var service in _asyncServices) { _logger.LogInformation($"Initializing async {service.GetType()}"); try { await service.InitAsync(); } catch (Exception e) { _logger.LogError(e, nameof(service.InitAsync)); } } _logger.LogInformation($"All components initialized async."); } _logger.LogInformation($"Starting..."); if (_syncServices.Count == 0) _logger.LogInformation($"No component found for sync start."); else { foreach (var service in _syncServices) { _logger.LogInformation($"Starting sync {service.GetType()}"); try { service.Start(); } catch (Exception ex) { _logger.LogError(ex, nameof(service.Start)); } } _logger.LogInformation($"All components started sync."); } if (_asyncServices.Count == 0) _logger.LogInformation($"No component found for async start."); else { foreach (var service in _asyncServices) { _logger.LogInformation($"Starting async {service.GetType()}"); try { await service.StartAsync(); } catch (Exception ex) { _logger.LogError(ex, nameof(service.StartAsync)); } } _logger.LogInformation($"All components started async."); } } public async Task StopAsync(CancellationToken cancellationToken) { _logger.LogInformation($"Stopping..."); if (_syncServices.Count == 0) _logger.LogInformation($"No component stopped for sync."); else { foreach (var service in _syncServices) { _logger.LogInformation($"Stopping sync {service.GetType()}"); try { service.Stop(); } catch (Exception ex) { _logger.LogError(ex, nameof(service.Stop)); } } _logger.LogInformation($"All components stopped sync."); } if (_asyncServices.Count == 0) _logger.LogInformation($"No component stopped for async."); else { foreach (var service in _asyncServices) { _logger.LogInformation($"Stopping async {service.GetType()}"); try { await service.StopAsync(); } catch (Exception ex) { _logger.LogError(ex, nameof(service.StopAsync)); } } _logger.LogInformation($"All components stopped async."); } } }