using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.FileProviders.Physical; using Microsoft.Extensions.Hosting; using System.Text.Json; namespace Toolkit.Foundation; public static class Test { public static IHostBuilder AddConfiguration(this IHostBuilder builder, string section) where TConfiguration : class, new() => builder.AddConfiguration(section, "Settings.json", null); public static IHostBuilder AddConfiguration(this IHostBuilder services) where TConfiguration : class, new() => services.AddConfiguration(typeof(TConfiguration).Name, "Settings.json", null); public static IHostBuilder AddConfiguration(this IHostBuilder builder, Action configurationDelegate) where TConfiguration : class, new() { TConfiguration configuration = new(); configurationDelegate.Invoke(configuration); return builder.AddConfiguration(typeof(TConfiguration).Name, "Settings.json", configuration); } public static IHostBuilder AddConfiguration(this IHostBuilder builder, Action configurationDelegate, string section) where TConfiguration : class, new() { TConfiguration configuration = new(); configurationDelegate.Invoke(configuration); return builder.AddConfiguration(section, "Settings.json", configuration); } public static IHostBuilder AddConfiguration(this IHostBuilder builder, TConfiguration configuration) where TConfiguration : class, new() => builder.AddConfiguration(configuration.GetType().Name, "Settings.json", configuration); public static IHostBuilder AddConfiguration(this IHostBuilder builder, object configuration) where TConfiguration : class, new() => builder.AddConfiguration(configuration.GetType().Name, "Settings.json", (TConfiguration?)configuration); public static IHostBuilder AddConfiguration(this IHostBuilder builder, string section, string path = "Settings.json", TConfiguration? defaultConfiguration = null, Action? serializerDelegate = null) where TConfiguration : class, new() { builder.ConfigureServices((context, services) => { HashSet sections = []; if (section.EndsWith(":*")) { section = section[..^1]; if (context.Configuration is ConfigurationRoot root) { foreach (KeyValuePair configuration in root.AsEnumerable()) { string[] segments = configuration.Key.Split(':'); if (segments.Length > 2) { string keyPrefix = string.Join(':', segments.Take(2)); if (!keyPrefix.EndsWith(":*")) { sections.Add(keyPrefix); } } } } } else { sections.Add(section); } foreach (string section in sections) { services.TryAddSingleton>(provider => { IFileInfo? fileInfo = null; if (provider.GetService() is IHostEnvironment hostEnvironment) { IFileProvider fileProvider = hostEnvironment.ContentRootFileProvider; fileInfo = fileProvider.GetFileInfo(path); } fileInfo ??= new PhysicalFileInfo(new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path))); return new ConfigurationFile(fileInfo); }); services.TryAddKeyedSingleton>(section, (provider, KeyAccelerator) => { JsonSerializerOptions? defaultSerializer = null; if (serializerDelegate is not null) { defaultSerializer = new JsonSerializerOptions(); serializerDelegate.Invoke(defaultSerializer); } return new ConfigurationSource(provider.GetRequiredService>(), section, defaultSerializer); }); //services.AddHostedService>(); services.TryAddKeyedTransient>(section, (provider, key) => new ConfigurationReader(provider.GetRequiredKeyedService>(key), provider.GetRequiredKeyedService>(key))); services.TryAddKeyedTransient>(section, (provider, key) => new ConfigurationWriter(provider.GetRequiredKeyedService>(key))); services.TryAddKeyedTransient>(section, (provider, key) => new ConfigurationFactory(() => defaultConfiguration ?? new TConfiguration())); services.AddTransient>(provider => new ConfigurationInitializer(provider.GetRequiredKeyedService>(section), provider.GetRequiredKeyedService>(section), provider.GetRequiredKeyedService>(section), provider.GetRequiredService())); services.AddTransient, ConfigurationInitializer>(provider => provider.GetRequiredService().Create>(section)); services.AddTransient, WritableConfiguration>(); services.TryAddKeyedTransient>(section, (provider, key) => new ConfigurationDescriptor(section, provider.GetRequiredKeyedService>(key))); services.AddTransient(provider => provider.GetRequiredKeyedService>(section)); services.AddTransient(provider => provider.GetRequiredKeyedService>(section).Value); } }); return builder; } } public class DefaultBuilder : HostBuilder { public static IHostBuilder Create() { return new HostBuilder() .UseContentRoot("Local", true) .ConfigureAppConfiguration((context, config) => { config.AddJsonFile("Settings.json", true, true); }) .ConfigureServices((context, services) => { services.AddScoped(provider => new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, parameters!))); services.AddSingleton(); services.AddScoped(); services.AddScoped(); services.AddTransient(); services.AddTransient(); services.AddScoped(); services.AddScoped>(provider => new ProxyService(provider.GetRequiredService())); services.AddScoped>(provider => new ProxyService(provider.GetRequiredService())); services.AddScoped>(provider => new ProxyService(provider.GetRequiredService())); services.AddScoped(); services.AddTransient(); services.AddTransient(); services.AddScoped(); services.AddTransient(); services.AddTransient(); services.AddSingleton(new ComponentScope("Root")); services.AddScoped(provider => new ComponentScopeCollection { new ComponentScopeDescriptor("Root", provider.GetRequiredService()) }); services.AddTransient(); services.AddHandler(); services.AddHandler(); services.AddInitializer(); services.AddHostedService(); }); } }