using PCC.Common.AssemblyInject.Interfaces; namespace PCC.Common.AssemblyInject.Services; internal class AssemblyInjectSyncStartStopWorker : IHostedService { private readonly ILogger> _logger; private readonly IReadOnlyCollection _services; public AssemblyInjectSyncStartStopWorker( 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}"); } } _services = 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(); } public Task StartAsync(CancellationToken cancellationToken) { _logger.LogInformation($"Initialization..."); if (_services.Count == 0) { _logger.LogInformation($"No component found."); } else { foreach (var service in _services) { _logger.LogInformation($"Initializing {service.GetType()}"); service.Init(); } _logger.LogInformation($"All components initialized."); } _logger.LogInformation($"Starting..."); if (_services.Count == 0) { _logger.LogInformation($"No component found."); } else { foreach (var service in _services) { _logger.LogInformation($"Starting {service.GetType()}"); service.Start(); } _logger.LogInformation($"All components started."); } return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { _logger.LogInformation($"Stopping..."); if (_services.Count == 0) { _logger.LogInformation($"No component stopped."); } else { foreach (var service in _services) { _logger.LogInformation($"Stopping {service.GetType()}"); service.Stop(); } _logger.LogInformation($"All components stopped."); } return Task.CompletedTask; } }