Initilize widget setting without starting its host

This commit is contained in:
TheXamlGuy
2024-01-31 22:33:23 +00:00
parent a2a5591502
commit 6dbe2db584
25 changed files with 125 additions and 83 deletions
@@ -7,7 +7,7 @@ public static class IServiceCollectionExtensions
{
public static IServiceCollection AddWidget(this IServiceCollection services)
{
services.AddTransient<IInitializer, WidgetExtensionInitializer>();
services.AddTransient<IInitialization, WidgetExtensionInitializer>();
services.AddTransient<IFactory<Type, IWidget>, WidgetFactory>();
services.AddHandler<WidgetExtensionEnumerator>();
+4 -4
View File
@@ -1,9 +1,9 @@
namespace Hyperbar.Widget;
using Microsoft.Extensions.Hosting;
namespace Hyperbar.Widget;
public interface IWidgetHost :
IInitializer
IHost
{
WidgetConfiguration Configuration { get; }
IServiceProvider Services { get; }
}
+2 -1
View File
@@ -1,3 +1,4 @@
namespace Hyperbar.Widget;
public interface IWidgetViewModel : IDisposable;
public interface IWidgetViewModel :
IDisposable;
+9 -4
View File
@@ -25,7 +25,7 @@ public class WidgetBuilder :
})
.ConfigureServices((context, services) =>
{
services.AddSingleton<IWidgetHost, WidgetHost>();
services.AddHostedService<WidgetService>();
services.AddScoped<IServiceFactory>(provider =>
new ServiceFactory((type, parameters) =>
ActivatorUtilities.CreateInstance(provider, type, parameters!)));
@@ -36,10 +36,13 @@ public class WidgetBuilder :
}
public static IWidgetBuilder Create() => new WidgetBuilder();
public IWidgetHost Build()
{
IHost host = hostBuilder.Build();
return host.Services.GetRequiredService<IWidgetHost>();
return (IWidgetHost)ActivatorUtilities.CreateInstance(host.Services,
typeof(WidgetHost), host);
}
public IWidgetBuilder UseConfiguration<TConfiguration>(Action<TConfiguration> configurationDelegate)
@@ -60,7 +63,9 @@ public class WidgetBuilder :
hostBuilder.ConfigureServices(services =>
{
services.AddHandler<WidgetConfigurationHandler>();
services.AddConfiguration<WidgetConfiguration>(section: configuration.GetType().Name, configuration: configuration);
services.AddConfiguration<WidgetConfiguration>(section: configuration.GetType().Name,
configuration: configuration);
services.AddConfiguration(configuration);
});
@@ -93,7 +98,7 @@ public class WidgetBuilder :
}
public IWidgetBuilder UseViewModelTemplate<TWidgetContent, TWidgetTemplate>()
where TWidgetContent :
where TWidgetContent :
IWidgetViewModel
{
if (viewModelTemplateRegistered)
+4 -4
View File
@@ -5,13 +5,13 @@ public class WidgetConfiguration
{
public string? Description { get; set; }
[JsonInclude]
internal Guid Id { get; set; } = Guid.NewGuid();
public string? Name { get; set; }
[JsonInclude]
internal bool IsAvailable { get; set; }
internal Guid Id { get; set; } = Guid.NewGuid();
[JsonInclude]
internal bool Enabled { get; set; }
}
public class WidgetConfiguration<TConfiguration>;
@@ -8,7 +8,7 @@ public class WidgetConfigurationHandler(IValue<WidgetAvailability> widgetAvailab
{
if (notification.Configuration is WidgetConfiguration configuration)
{
await widgetAvailability.SetAsync(args => args with { Value = configuration.IsAvailable });
await widgetAvailability.SetAsync(args => args with { Value = configuration.Enabled });
}
}
}
+5 -3
View File
@@ -2,8 +2,9 @@
namespace Hyperbar.Widget;
public class WidgetExtensionHandler(IProxyServiceCollection<IWidgetBuilder> typedServices,
IServiceProvider provider) :
public class WidgetExtensionHandler(IServiceProvider provider,
IMediator mediator,
IProxyServiceCollection<IWidgetBuilder> typedServices) :
INotificationHandler<Created<WidgetExtension>>
{
public async Task Handle(Created<WidgetExtension> notification,
@@ -21,7 +22,8 @@ public class WidgetExtensionHandler(IProxyServiceCollection<IWidgetBuilder> type
});
IWidgetHost host = builder.Build();
await host.InitializeAsync();
await mediator.PublishAsync(new Created<IWidgetHost>(host),
cancellationToken);
}
}
}
@@ -1,7 +1,7 @@
namespace Hyperbar.Widget;
public class WidgetExtensionInitializer(IMediator mediator) :
IInitializer
IInitialization
{
public async Task InitializeAsync() =>
await mediator.PublishAsync<Enumerate<WidgetExtension>>();
+22 -29
View File
@@ -1,59 +1,52 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace Hyperbar.Widget;
public class WidgetHost :
INotificationHandler<Changed<WidgetAvailability>>,
public sealed class WidgetHost :
IWidgetHost
{
private readonly IEnumerable<IInitializer> initializers;
private readonly IHost host;
private readonly IMediator mediator;
private readonly IProxyService<IMediator> proxyMediator;
private readonly IServiceProvider services;
public WidgetHost(IServiceProvider services,
public WidgetHost(IHost host,
IMediator mediator,
IEnumerable<IInitializer> initializers,
IProxyService<IMediator> proxyMediator)
{
this.services = services;
this.host = host;
this.mediator = mediator;
this.initializers = initializers;
this.proxyMediator = proxyMediator;
mediator.Subscribe(this);
}
public WidgetConfiguration Configuration =>
services.GetRequiredService<WidgetConfiguration>();
public WidgetConfiguration Configuration =>
Services.GetRequiredService<WidgetConfiguration>();
public IServiceProvider Services => services;
public IServiceProvider Services => host.Services;
public async Task Handle(Changed<WidgetAvailability> notification,
CancellationToken cancellationToken)
public void Dispose()
{
if (notification.Value is WidgetAvailability widgetAvailability)
{
if (widgetAvailability.Value)
{
await StartAsync();
}
}
}
public async Task InitializeAsync()
public async Task StartAsync(CancellationToken cancellationToken = default)
{
foreach (IInitializer initializer in initializers)
{
await initializer.InitializeAsync();
}
}
await host.StartAsync(cancellationToken);
private async Task StartAsync()
{
if (proxyMediator.Proxy is IMediator mediator)
{
await mediator.PublishAsync(new Started<IWidgetHost>(this));
await mediator.PublishAsync(new Started<IWidgetHost>(this),
cancellationToken);
}
await this.mediator.PublishAsync(new Started<IWidgetHost>(this),
cancellationToken);
}
public async Task StopAsync(CancellationToken cancellationToken = default)
{
await host.StopAsync(cancellationToken);
}
}
+21 -12
View File
@@ -3,25 +3,34 @@
namespace Hyperbar.Widget;
public class WidgetHostHandler(IMediator mediator) :
INotificationHandler<Started<IWidgetHost>>,
INotificationHandler<Stopped<IWidgetHost>>
INotificationHandler<Created<IWidgetHost>>
{
public async Task Handle(Started<IWidgetHost> notification,
//public async Task Handle(Started<IWidgetHost> notification,
// CancellationToken cancellationToken)
//{
// if (notification.Value is IWidgetHost host)
// {
// if (host.Services.GetService<IWidgetViewModel>() is IWidgetViewModel viewModel)
// {
// await mediator.PublishAsync(new Created<IWidgetViewModel>(viewModel),
// nameof(WidgetViewModel), cancellationToken);
// }
// }
//}
public async Task Handle(Created<IWidgetHost> notification,
CancellationToken cancellationToken)
{
if (notification.Value is IWidgetHost host)
{
if (host.Services.GetService<IWidgetViewModel>() is IWidgetViewModel viewModel)
if (host.Services.GetServices<IInitialization>() is
IEnumerable<IInitialization> initializations)
{
await mediator.PublishAsync(new Created<IWidgetViewModel>(viewModel),
nameof(WidgetViewModel), cancellationToken);
foreach (IInitialization initialization in initializations)
{
await initialization.InitializeAsync();
}
}
}
}
public Task Handle(Stopped<IWidgetHost> notification,
CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
namespace Hyperbar.Widget;
public class WidgetMonitor :
IInitializer
IInitialization
{
public Task InitializeAsync()
{
+27
View File
@@ -0,0 +1,27 @@
using Microsoft.Extensions.Hosting;
namespace Hyperbar.Widget;
public class WidgetService :
IHostedService
{
private readonly IEnumerable<IInitialization> initializers;
public WidgetService(IEnumerable<IInitialization> initializers)
{
this.initializers = initializers;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
foreach (IInitialization initializer in initializers)
{
await initializer.InitializeAsync();
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}