using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System.Reflection; namespace Hyperbar.Widget; public class WidgetBuilder : IWidgetBuilder { private readonly IHostBuilder hostBuilder; private bool configurationRegistered; private bool viewModelTemplateRegistered; private WidgetBuilder() { hostBuilder = new HostBuilder() .UseContentRoot(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Assembly.GetEntryAssembly()?.GetName().Name!), true) .ConfigureAppConfiguration(config => { config.AddJsonFile("Settings.json", true, true); }) .ConfigureServices((context, services) => { services.AddSingleton(); services.AddScoped(provider => new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, parameters!))); services.AddSingleton(); services.AddSingleton(); services.AddTransient(); services.AddTransient(); services.AddScoped(); services.AddScoped(); services.AddHandler(); services.AddValueChangedNotification((config) => (args) => { args.Value = config.IsEnabled; }); }); } public static IWidgetBuilder Create() => new WidgetBuilder(); public IWidgetHost Build() { IHost host = hostBuilder.Build(); return host.Services.GetRequiredService(); } public IWidgetBuilder UseConfiguration(Action configurationDelegate) where TConfiguration : WidgetConfiguration, new() { if (configurationRegistered) { return this; } configurationRegistered = true; TConfiguration configuration = new(); configurationDelegate(configuration); hostBuilder.ConfigureServices(services => { services.AddHandler(); services.AddConfiguration(section: configuration.GetType().Name, configuration: configuration); services.AddConfiguration(configuration); }); return this; } public IWidgetBuilder ConfigureServices(Action configureDelegate) { hostBuilder.ConfigureServices(configureDelegate); return this; } public IWidgetBuilder UseViewModel() where TViewModel : IWidgetViewModel { if (viewModelTemplateRegistered) { return this; } viewModelTemplateRegistered = true; hostBuilder.ConfigureServices(services => { services.AddWidgetTemplate(); }); return this; } public IWidgetBuilder UseViewModelTemplate() where TWidgetContent : IWidgetViewModel { if (viewModelTemplateRegistered) { return this; } viewModelTemplateRegistered = true; hostBuilder.ConfigureServices(services => { services.AddWidgetTemplate(); }); return this; } }