using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using StellaOps.DependencyInjection; using StellaOps.Plugin.Hosting; using StellaOps.Plugin.Internal; using System; using System.Collections.Generic; using System.Linq; namespace StellaOps.Plugin.DependencyInjection; public static class PluginDependencyInjectionExtensions { public static IServiceCollection RegisterPluginRoutines( this IServiceCollection services, IConfiguration configuration, PluginHostOptions options, ILogger? logger = null) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } var loadResult = PluginHost.LoadPlugins(options, logger); foreach (var plugin in loadResult.Plugins) { PluginServiceRegistration.RegisterAssemblyMetadata(services, plugin.Assembly, logger); foreach (var routine in CreateRoutines(plugin.Assembly)) { logger?.LogDebug( "Registering DI routine '{RoutineType}' from plugin '{PluginAssembly}'.", routine.GetType().FullName, plugin.Assembly.FullName); routine.Register(services, configuration); } } if (loadResult.MissingOrderedPlugins.Count > 0) { logger?.LogWarning( "Some ordered plugins were not found: {Missing}", string.Join(", ", loadResult.MissingOrderedPlugins)); } return services; } private static IEnumerable CreateRoutines(System.Reflection.Assembly assembly) { foreach (var type in assembly.GetLoadableTypes()) { if (type is null || type.IsAbstract || type.IsInterface) { continue; } if (!typeof(IDependencyInjectionRoutine).IsAssignableFrom(type)) { continue; } object? instance; try { instance = Activator.CreateInstance(type); } catch { continue; } if (instance is IDependencyInjectionRoutine routine) { yield return routine; } } } }