From 814c8062406a82f44bd2cfb21428e49bcd82eef8 Mon Sep 17 00:00:00 2001 From: TheXamlGuy Date: Thu, 11 Jan 2024 19:52:48 +0000 Subject: [PATCH] More refactoring --- .../IPrimaryCommandConfiguration.cs | 4 +- .../KeyAcceleratorCommandConfiguration.cs | 2 +- .../PrimaryWidgetConfiguration.cs | 2 +- ...rimaryWidgetConfigurationChangedHandler.cs | 22 -------- .../PrimaryWidgetProvider.cs | 10 ++-- .../PrimaryWidgetViewModel.cs | 4 +- .../ProcessCommandConfiguration.cs | 2 +- .../WidgetComponentMapping.cs | 25 --------- .../WidgetComponentViewModelFactory.cs | 26 ++++++++++ .../IServiceCollectionExtensions.cs | 10 +++- Hyperbar/Lifecycles/IFactory.cs | 6 +++ .../Mediators/NotficationPipelineHandler.cs | 18 +++++++ Hyperbar/Views/CollectionChanged.cs | 5 -- Hyperbar/Views/CollectionChanging.cs | 5 ++ .../Views/IObservableCollectionViewModel.cs | 11 ++++ .../Views/ObservableCollectionViewModel.cs | 51 +++++++++++++------ 16 files changed, 125 insertions(+), 78 deletions(-) delete mode 100644 Hyperbar.Windows.Primary/PrimaryWidgetConfigurationChangedHandler.cs delete mode 100644 Hyperbar.Windows.Primary/WidgetComponentMapping.cs create mode 100644 Hyperbar.Windows.Primary/WidgetComponentViewModelFactory.cs create mode 100644 Hyperbar/Lifecycles/IFactory.cs create mode 100644 Hyperbar/Mediators/NotficationPipelineHandler.cs delete mode 100644 Hyperbar/Views/CollectionChanged.cs create mode 100644 Hyperbar/Views/CollectionChanging.cs create mode 100644 Hyperbar/Views/IObservableCollectionViewModel.cs diff --git a/Hyperbar.Windows.Primary/IPrimaryCommandConfiguration.cs b/Hyperbar.Windows.Primary/IPrimaryCommandConfiguration.cs index c2da743..69750ea 100644 --- a/Hyperbar.Windows.Primary/IPrimaryCommandConfiguration.cs +++ b/Hyperbar.Windows.Primary/IPrimaryCommandConfiguration.cs @@ -6,5 +6,7 @@ namespace Hyperbar.Windows.Primary; [JsonDerivedType(typeof(ProcessCommandConfiguration), typeDiscriminator: "ProcessCommand")] public class PrimaryCommandConfiguration { - public string? Icon { get; set; } + public required string Id { get; set; } + + public required string Icon { get; set; } } \ No newline at end of file diff --git a/Hyperbar.Windows.Primary/KeyAcceleratorCommandConfiguration.cs b/Hyperbar.Windows.Primary/KeyAcceleratorCommandConfiguration.cs index 9a5bc7c..83963a0 100644 --- a/Hyperbar.Windows.Primary/KeyAcceleratorCommandConfiguration.cs +++ b/Hyperbar.Windows.Primary/KeyAcceleratorCommandConfiguration.cs @@ -3,7 +3,7 @@ public class KeyAcceleratorCommandConfiguration : PrimaryCommandConfiguration { - public int Key { get; set; } + public required int Key { get; set; } public int[]? Modifiers { get; set; } } diff --git a/Hyperbar.Windows.Primary/PrimaryWidgetConfiguration.cs b/Hyperbar.Windows.Primary/PrimaryWidgetConfiguration.cs index a0a5bc1..f443dca 100644 --- a/Hyperbar.Windows.Primary/PrimaryWidgetConfiguration.cs +++ b/Hyperbar.Windows.Primary/PrimaryWidgetConfiguration.cs @@ -5,6 +5,6 @@ public class PrimaryWidgetConfiguration : { public static PrimaryWidgetConfiguration Defaults => new() { - new KeyAcceleratorCommandConfiguration { Icon = "\uE720", Key = 91, Modifiers = [] } + new KeyAcceleratorCommandConfiguration { Id = $"{Guid.NewGuid()}", Icon = "\uE720", Key = 91, Modifiers = [] } }; } \ No newline at end of file diff --git a/Hyperbar.Windows.Primary/PrimaryWidgetConfigurationChangedHandler.cs b/Hyperbar.Windows.Primary/PrimaryWidgetConfigurationChangedHandler.cs deleted file mode 100644 index 211d64e..0000000 --- a/Hyperbar.Windows.Primary/PrimaryWidgetConfigurationChangedHandler.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Hyperbar.Windows.Primary; - -public class PrimaryWidgetConfigurationChangedHandler : - INotificationHandler> -{ - private readonly IMediator mediator; - private readonly IEnumerable items; - - public PrimaryWidgetConfigurationChangedHandler(IMediator mediator, - IEnumerable items) - { - this.mediator = mediator; - this.items = items; - } - - public async ValueTask Handle(ConfigurationChanged notification, - CancellationToken cancellationToken) - { - await mediator.PublishAsync(new CollectionChanged>(items), - cancellationToken); - } -} diff --git a/Hyperbar.Windows.Primary/PrimaryWidgetProvider.cs b/Hyperbar.Windows.Primary/PrimaryWidgetProvider.cs index 41d47e2..416cfe2 100644 --- a/Hyperbar.Windows.Primary/PrimaryWidgetProvider.cs +++ b/Hyperbar.Windows.Primary/PrimaryWidgetProvider.cs @@ -6,9 +6,11 @@ namespace Hyperbar.Windows.Primary; public class PrimaryWidgetProvider : IWidgetProvider { - public void Create(HostBuilderContext comtext, IServiceCollection services) => + public void Create(HostBuilderContext comtext, IServiceCollection services) => services.AddConfiguration() - .AddHandler() - .AddHandler() - .AddWidgetTemplate(); + .AddTransient>, WidgetComponentViewModelFactory>() + .AddWidgetTemplate() + .AddNotificationPipeline, + ValueChanging>>(); + } \ No newline at end of file diff --git a/Hyperbar.Windows.Primary/PrimaryWidgetViewModel.cs b/Hyperbar.Windows.Primary/PrimaryWidgetViewModel.cs index 42e89c9..44656db 100644 --- a/Hyperbar.Windows.Primary/PrimaryWidgetViewModel.cs +++ b/Hyperbar.Windows.Primary/PrimaryWidgetViewModel.cs @@ -4,8 +4,8 @@ namespace Hyperbar.Windows.Primary; public class PrimaryWidgetViewModel(ITemplateFactory templateFactory, IServiceFactory serviceFactory, IMediator mediator, - IEnumerable items) : - ObservableCollectionViewModel(serviceFactory, mediator, items), + IFactory> factory) : + ObservableCollectionViewModel(serviceFactory, mediator, factory), IWidgetViewModel, ITemplatedViewModel { diff --git a/Hyperbar.Windows.Primary/ProcessCommandConfiguration.cs b/Hyperbar.Windows.Primary/ProcessCommandConfiguration.cs index 2a64c15..e59494a 100644 --- a/Hyperbar.Windows.Primary/ProcessCommandConfiguration.cs +++ b/Hyperbar.Windows.Primary/ProcessCommandConfiguration.cs @@ -3,5 +3,5 @@ public class ProcessCommandConfiguration : PrimaryCommandConfiguration { - public string? Path { get; set; } + public required string Path { get; set; } } \ No newline at end of file diff --git a/Hyperbar.Windows.Primary/WidgetComponentMapping.cs b/Hyperbar.Windows.Primary/WidgetComponentMapping.cs deleted file mode 100644 index 5b2cf80..0000000 --- a/Hyperbar.Windows.Primary/WidgetComponentMapping.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Hyperbar.Windows.Primary; - -public class WidgetComponentMapping(PrimaryWidgetConfiguration configuration, - IServiceFactory service, - IMediator mediator) : - IMappingHandler> -{ - public IEnumerable Handle() - { - foreach (var item in configuration) - { - if (item is KeyAcceleratorCommandConfiguration keyAcceleratorCommandConfiguration) - { - yield return service.Create(keyAcceleratorCommandConfiguration.Icon, new Action(async () => - await mediator.SendAsync(new KeyAcceleratorRequest((VirtualKey)keyAcceleratorCommandConfiguration.Key, - keyAcceleratorCommandConfiguration.Modifiers?.Select(modifier => (VirtualKey)modifier).ToArray())))); - } - - if (item is ProcessCommandConfiguration processCommandConfiguration) - { - - } - } - } -} \ No newline at end of file diff --git a/Hyperbar.Windows.Primary/WidgetComponentViewModelFactory.cs b/Hyperbar.Windows.Primary/WidgetComponentViewModelFactory.cs new file mode 100644 index 0000000..a317906 --- /dev/null +++ b/Hyperbar.Windows.Primary/WidgetComponentViewModelFactory.cs @@ -0,0 +1,26 @@ +namespace Hyperbar.Windows.Primary; + +public class WidgetComponentViewModelFactory(PrimaryWidgetConfiguration configuration, + IServiceFactory service, + IMediator mediator) : + IFactory> +{ + public IEnumerable Create() + { + foreach (PrimaryCommandConfiguration item in configuration) + { + if (item is KeyAcceleratorCommandConfiguration keyAcceleratorCommandConfiguration) + { + yield return service.Create(keyAcceleratorCommandConfiguration.Icon, new Action(async () => + await mediator.SendAsync(new KeyAcceleratorRequest((VirtualKey)keyAcceleratorCommandConfiguration.Key, + keyAcceleratorCommandConfiguration.Modifiers?.Select(modifier => (VirtualKey)modifier).ToArray())))); + } + + if (item is ProcessCommandConfiguration processCommandConfiguration) + { + yield return service.Create(processCommandConfiguration.Icon, new Action(async () => + await mediator.SendAsync(new ProcessRequest(processCommandConfiguration.Path)))); + } + } + } +} \ No newline at end of file diff --git a/Hyperbar/Extensions/IServiceCollectionExtensions.cs b/Hyperbar/Extensions/IServiceCollectionExtensions.cs index f382a8f..2885e30 100644 --- a/Hyperbar/Extensions/IServiceCollectionExtensions.cs +++ b/Hyperbar/Extensions/IServiceCollectionExtensions.cs @@ -16,8 +16,16 @@ public static class IServiceCollectionExtensions return services.AddConfiguration(typeof(TConfiguration).Name, "Settings.json", null); } + public static IServiceCollection AddNotificationPipeline(this IServiceCollection services) + where TFromNotification : + INotification + where TToNotification : + INotification, new() + { + return services.AddHandler>(); + } + public static IServiceCollection AddConfiguration(this IServiceCollection services, - IConfiguration configuration, TConfiguration? defaults = null) where TConfiguration : class, new() diff --git a/Hyperbar/Lifecycles/IFactory.cs b/Hyperbar/Lifecycles/IFactory.cs new file mode 100644 index 0000000..9713b38 --- /dev/null +++ b/Hyperbar/Lifecycles/IFactory.cs @@ -0,0 +1,6 @@ +namespace Hyperbar; + +public interface IFactory +{ + T Create(); +} \ No newline at end of file diff --git a/Hyperbar/Mediators/NotficationPipelineHandler.cs b/Hyperbar/Mediators/NotficationPipelineHandler.cs new file mode 100644 index 0000000..4607b10 --- /dev/null +++ b/Hyperbar/Mediators/NotficationPipelineHandler.cs @@ -0,0 +1,18 @@ +namespace Hyperbar; + +public class NotficationPipelineHandler(IMediator mediator) : + INotificationHandler, + IHandler + where TFromNotification : + INotification + where ToNotification : + INotification, new() +{ + private readonly IMediator mediator = mediator; + + public ValueTask Handle(TFromNotification notification, CancellationToken cancellationToken) + { + return mediator.PublishAsync(new ToNotification(), + cancellationToken); + } +} diff --git a/Hyperbar/Views/CollectionChanged.cs b/Hyperbar/Views/CollectionChanged.cs deleted file mode 100644 index f6cd378..0000000 --- a/Hyperbar/Views/CollectionChanged.cs +++ /dev/null @@ -1,5 +0,0 @@ -using System.Collections; - -namespace Hyperbar; - -public record CollectionChanged(TCollection Items) : INotification where TCollection : IEnumerable; diff --git a/Hyperbar/Views/CollectionChanging.cs b/Hyperbar/Views/CollectionChanging.cs new file mode 100644 index 0000000..e4ecc13 --- /dev/null +++ b/Hyperbar/Views/CollectionChanging.cs @@ -0,0 +1,5 @@ +using System.Collections; + +namespace Hyperbar; + +public record ValueChanging : INotification; diff --git a/Hyperbar/Views/IObservableCollectionViewModel.cs b/Hyperbar/Views/IObservableCollectionViewModel.cs new file mode 100644 index 0000000..21b3853 --- /dev/null +++ b/Hyperbar/Views/IObservableCollectionViewModel.cs @@ -0,0 +1,11 @@ +using System.Collections; +using System.Collections.Specialized; + +namespace Hyperbar; + +public interface IObservableCollectionViewModel : + IList, + IList, + IReadOnlyList, + INotifyCollectionChanged, + INotificationHandler>>; diff --git a/Hyperbar/Views/ObservableCollectionViewModel.cs b/Hyperbar/Views/ObservableCollectionViewModel.cs index 91bb07a..31401e7 100644 --- a/Hyperbar/Views/ObservableCollectionViewModel.cs +++ b/Hyperbar/Views/ObservableCollectionViewModel.cs @@ -5,13 +5,9 @@ using System.Collections.Specialized; namespace Hyperbar; -public partial class ObservableCollectionViewModel : +public partial class ObservableCollectionViewModel : ObservableObject, - IList, - IList, - IReadOnlyList, - INotifyCollectionChanged, - INotificationHandler>> + IObservableCollectionViewModel { public ObservableCollection collection = []; private readonly SynchronizationContext? context; @@ -28,6 +24,23 @@ public partial class ObservableCollectionViewModel : collection.CollectionChanged += OnCollectionChanged; } + public ObservableCollectionViewModel(IServiceFactory serviceFactory, + IMediator mediator, + IFactory> factory) + { + context = SynchronizationContext.Current; + + this.serviceFactory = serviceFactory; + mediator.Subscribe(this); + + collection.CollectionChanged += OnCollectionChanged; + + if (factory is not null && factory.Create() is { } items) + { + AddRange(factory.Create()); + } + } + public ObservableCollectionViewModel(IServiceFactory serviceFactory, IMediator mediator, IEnumerable items) @@ -158,14 +171,14 @@ public partial class ObservableCollectionViewModel : IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)collection).GetEnumerator(); - public ValueTask Handle(CollectionChanged> notification, - CancellationToken cancellationToken) - { - context?.Post(state => Clear(), null); - AddRange(notification.Items); + //public ValueTask Handle(CollectionChanged> notification, + // CancellationToken cancellationToken) + //{ + // context?.Post(state => Clear(), null); + // AddRange(notification.Items); - return ValueTask.CompletedTask; - } + // return ValueTask.CompletedTask; + //} public int IndexOf(TItem item) => collection.IndexOf(item); @@ -212,9 +225,17 @@ public partial class ObservableCollectionViewModel : protected virtual void SetItem(int index, TItem item) => collection[index] = item; - private static bool IsCompatibleObject(object? value) => (value is TItem) || (value == null && default(TItem) == null); + private static bool IsCompatibleObject(object? value) => (value is TItem) || + (value == null && default(TItem) == null); - private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs args) => CollectionChanged?.Invoke(this, args); + private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs args) => + CollectionChanged?.Invoke(this, args); + + public ValueTask Handle(ValueChanging> notification, + CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } } public class ObservableCollectionViewModel(IServiceFactory serviceFactory, IMediator mediator) :