This commit is contained in:
TheXamlGuy
2024-02-01 22:13:45 +00:00
parent 6dbe2db584
commit 4edb0a7eb5
21 changed files with 126 additions and 85 deletions
@@ -4,8 +4,9 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:windows="using:Hyperbar.UI.Windows">
<FlipView
<Button>sfsdf</Button>
<!--<FlipView
Width="360"
ItemTemplateSelector="{Binding Converter={windows:DataTemplateConverter}}"
ItemsSource="{Binding}" />
ItemsSource="{Binding}" />-->
</UserControl>
@@ -7,9 +7,9 @@ public class PrimaryWidgetConfigurationHandler(IMediator mediator,
IFactory<PrimaryCommandConfiguration, IWidgetComponentViewModel?> factory,
IProvider<PrimaryCommandConfiguration, IWidgetComponentViewModel?> provider,
ICache<(Guid ParentId, Guid Id), PrimaryCommandConfiguration> cache) :
INotificationHandler<ConfigurationChanged<PrimaryWidgetConfiguration>>
INotificationHandler<Changed<PrimaryWidgetConfiguration>>
{
public async Task Handle(ConfigurationChanged<PrimaryWidgetConfiguration> notification,
public async Task Handle(Changed<PrimaryWidgetConfiguration> notification,
CancellationToken cancellationToken)
{
List<KeyValuePair<(Guid ParentId, Guid Id), PrimaryCommandConfiguration>> items = [];
@@ -13,6 +13,7 @@ public static class IServiceCollectionExtensions
services.AddHandler<WidgetExtensionEnumerator>();
services.AddHandler<WidgetExtensionHandler>();
services.AddHandler<WidgetHostHandler>();
services.AddHandler<WidgetStartedHandler>();
return services;
}
@@ -0,0 +1,21 @@
namespace Hyperbar.Widget;
public class WidgetAvailabilityChangedHandler(IWidgetHost host) :
INotificationHandler<Changed<WidgetAvailability>>
{
public async Task Handle(Changed<WidgetAvailability> args,
CancellationToken cancellationToken)
{
if (args.Value is WidgetAvailability widgetAvailability)
{
if (widgetAvailability.Value)
{
await host.StartAsync(cancellationToken);
}
else
{
await host.StopAsync(cancellationToken);
}
}
}
}
+8 -8
View File
@@ -25,13 +25,18 @@ public class WidgetBuilder :
})
.ConfigureServices((context, services) =>
{
services.AddHostedService<WidgetService>();
services.AddSingleton<IWidgetHost, WidgetHost>();
services.AddScoped<IServiceFactory>(provider =>
new ServiceFactory((type, parameters) =>
ActivatorUtilities.CreateInstance(provider, type, parameters!)));
services.AddScoped<IMediator, Mediator>();
services.AddScoped<IDisposer, Disposer>();
services.AddSingleton<IValue<WidgetAvailability>, Value<WidgetAvailability>>();
services.AddHandler<WidgetAvailabilityChangedHandler>();
services.AddValueChangedNotification<WidgetConfiguration,
WidgetAvailability>((config) => (args) =>
{
args.Value = config.IsEnabled;
});
});
}
@@ -40,9 +45,7 @@ public class WidgetBuilder :
public IWidgetHost Build()
{
IHost host = hostBuilder.Build();
return (IWidgetHost)ActivatorUtilities.CreateInstance(host.Services,
typeof(WidgetHost), host);
return host.Services.GetRequiredService<IWidgetHost>();
}
public IWidgetBuilder UseConfiguration<TConfiguration>(Action<TConfiguration> configurationDelegate)
@@ -56,7 +59,6 @@ public class WidgetBuilder :
}
configurationRegistered = true;
TConfiguration configuration = new();
configurationDelegate(configuration);
@@ -88,7 +90,6 @@ public class WidgetBuilder :
}
viewModelTemplateRegistered = true;
hostBuilder.ConfigureServices(services =>
{
services.AddWidgetTemplate<TViewModel>();
@@ -107,7 +108,6 @@ public class WidgetBuilder :
}
viewModelTemplateRegistered = true;
hostBuilder.ConfigureServices(services =>
{
services.AddWidgetTemplate<TWidgetContent, TWidgetTemplate>();
+1 -1
View File
@@ -11,7 +11,7 @@ public class WidgetConfiguration
internal Guid Id { get; set; } = Guid.NewGuid();
[JsonInclude]
internal bool Enabled { get; set; }
internal bool IsEnabled { get; set; }
}
public class WidgetConfiguration<TConfiguration>;
@@ -1,4 +0,0 @@
namespace Hyperbar.Widget;
public record WidgetConfigurationChanged<TConfiguration> : INotification;
+10 -5
View File
@@ -1,14 +1,19 @@
namespace Hyperbar.Widget;
public class WidgetConfigurationHandler(IValue<WidgetAvailability> widgetAvailability) :
INotificationHandler<ConfigurationChanged<WidgetConfiguration>>
public class WidgetConfigurationHandler(IEnumerable<IConfigurationValueChangedNotification<WidgetConfiguration>>
configurationValueChangedNotifications ) :
INotificationHandler<Changed<WidgetConfiguration>>
{
public async Task Handle(ConfigurationChanged<WidgetConfiguration> notification,
public async Task Handle(Changed<WidgetConfiguration> args,
CancellationToken cancellationToken)
{
if (notification.Configuration is WidgetConfiguration configuration)
if (args.Value is WidgetConfiguration configuration)
{
await widgetAvailability.SetAsync(args => args with { Value = configuration.Enabled });
foreach (IConfigurationValueChangedNotification<WidgetConfiguration> notification in
configurationValueChangedNotifications)
{
await notification.PublishAsync(configuration);
}
}
}
}
+6 -8
View File
@@ -6,15 +6,15 @@ namespace Hyperbar.Widget;
public sealed class WidgetHost :
IWidgetHost
{
private readonly IHost host;
private readonly IServiceProvider services;
private readonly IMediator mediator;
private readonly IProxyService<IMediator> proxyMediator;
public WidgetHost(IHost host,
public WidgetHost(IServiceProvider services,
IMediator mediator,
IProxyService<IMediator> proxyMediator)
{
this.host = host;
this.services = services;
this.mediator = mediator;
this.proxyMediator = proxyMediator;
@@ -24,7 +24,7 @@ public sealed class WidgetHost :
public WidgetConfiguration Configuration =>
Services.GetRequiredService<WidgetConfiguration>();
public IServiceProvider Services => host.Services;
public IServiceProvider Services => services;
public void Dispose()
{
@@ -33,8 +33,6 @@ public sealed class WidgetHost :
public async Task StartAsync(CancellationToken cancellationToken = default)
{
await host.StartAsync(cancellationToken);
if (proxyMediator.Proxy is IMediator mediator)
{
await mediator.PublishAsync(new Started<IWidgetHost>(this),
@@ -45,8 +43,8 @@ public sealed class WidgetHost :
cancellationToken);
}
public async Task StopAsync(CancellationToken cancellationToken = default)
public Task StopAsync(CancellationToken cancellationToken = default)
{
await host.StopAsync(cancellationToken);
return Task.CompletedTask;
}
}
+1 -14
View File
@@ -2,22 +2,9 @@
namespace Hyperbar.Widget;
public class WidgetHostHandler(IMediator mediator) :
public class WidgetHostHandler :
INotificationHandler<Created<IWidgetHost>>
{
//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)
{
+20
View File
@@ -0,0 +1,20 @@
using Microsoft.Extensions.DependencyInjection;
namespace Hyperbar.Widget;
public class WidgetStartedHandler(IMediator mediator) :
INotificationHandler<Started<IWidgetHost>>
{
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);
}
}
}
}
@@ -4,9 +4,9 @@ namespace Hyperbar.Windows;
public class AppConfigurationChangedHandler(DesktopBar desktopFlyout,
AppConfiguration configuration) :
INotificationHandler<ConfigurationChanged<AppConfiguration>>
INotificationHandler<Changed<AppConfiguration>>
{
public Task Handle(ConfigurationChanged<AppConfiguration> notification, CancellationToken cancellationToken)
public Task Handle(Changed<AppConfiguration> notification, CancellationToken cancellationToken)
{
desktopFlyout.Placement = configuration.Placement;
return Task.CompletedTask;
@@ -1,5 +0,0 @@
namespace Hyperbar;
public record ConfigurationChanged<TConfiguration>(TConfiguration Configuration) : INotification
where TConfiguration :
class;
@@ -1,6 +1,7 @@
namespace Hyperbar;
public class ConfigurationInitializer<TConfiguration>(IConfigurationMonitor<TConfiguration> monitor,
public class ConfigurationInitializer<TConfiguration>(IMediator mediator,
IConfigurationMonitor<TConfiguration> monitor,
IConfigurationReader<TConfiguration> reader,
IConfigurationWriter<TConfiguration> writer,
IConfigurationFactory<TConfiguration> factory) :
@@ -11,14 +12,16 @@ public class ConfigurationInitializer<TConfiguration>(IConfigurationMonitor<TCon
{
public async Task InitializeAsync()
{
if (!reader.TryRead(out TConfiguration? _))
if (!reader.TryRead(out TConfiguration? configuration))
{
if (factory.Create() is object defaultConfiguration)
{
configuration = (TConfiguration?)defaultConfiguration;
writer.Write(defaultConfiguration);
}
}
await mediator.PublishAsync(new Changed<TConfiguration>(configuration));
await monitor.InitializeAsync();
}
}
@@ -16,7 +16,7 @@ public class ConfigurationMonitor<TConfiguration>(IConfigurationFile<TConfigurat
{
if (reader.Read() is { } configuration)
{
await mediator.PublishAsync(new ConfigurationChanged<TConfiguration>(configuration));
await mediator.PublishAsync(new Changed<TConfiguration>(configuration));
}
}
@@ -0,0 +1,24 @@
namespace Hyperbar;
public class ConfigurationValueChangedNotification<TConfiguration, TValue>(IMediator mediator,
Func<TConfiguration, Action<TValue>> factory) :
IConfigurationValueChangedNotification<TConfiguration>
where TConfiguration :
class
where TValue :
class, new()
{
private TValue? value;
public async Task PublishAsync(TConfiguration configuration)
{
TValue newValue = new();
factory(configuration).Invoke(newValue);
if (value is null || !value.Equals(newValue))
{
value = newValue;
await mediator.PublishAsync(new Changed<TValue>(value));
}
}
}
@@ -0,0 +1,6 @@
namespace Hyperbar;
public interface IConfigurationValueChangedNotification<TConfiguration>
{
Task PublishAsync(TConfiguration configuration);
}
@@ -9,6 +9,20 @@ namespace Hyperbar;
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddValueChangedNotification<TConfiguration, TValue>(this IServiceCollection services,
Func<TConfiguration, Action<TValue>> factory)
where TConfiguration :
class
where TValue :
class, new()
{
services.AddSingleton<IConfigurationValueChangedNotification<TConfiguration>>(provider =>
new ConfigurationValueChangedNotification<TConfiguration, TValue>(provider.GetRequiredService<IMediator>(),
factory));
return services;
}
public static IServiceCollection AddCache<TKey, TValue>(this IServiceCollection services)
where TKey :
notnull
-9
View File
@@ -1,9 +0,0 @@
namespace Hyperbar;
public interface IValue<TValue>
where TValue :
notnull, new()
{
Task SetAsync(Func<TValue, TValue> updateDelgate);
}
-21
View File
@@ -1,21 +0,0 @@
namespace Hyperbar;
public class Value<TValue>(IMediator mediator) :
IValue<TValue>
where TValue :
notnull, new ()
{
private TValue? current;
public async Task SetAsync(Func<TValue, TValue> updateDelgate)
{
if (updateDelgate.Invoke(current ?? new TValue()) is TValue value)
{
if (current is null || !value.Equals(current))
{
current = value;
await mediator.PublishAsync(new Changed<TValue>(current));
}
}
}
}
+1 -1
View File
@@ -5,6 +5,6 @@ public interface INotificationHandler<in TNotification> :
where TNotification :
INotification
{
Task Handle(TNotification notification,
Task Handle(TNotification args,
CancellationToken cancellationToken);
}