diff --git a/Hyperbar.Windows.Contextual/ContextualWidgetProvider.cs b/Hyperbar.Windows.Contextual/ContextualWidgetProvider.cs index bc8aa81..1035803 100644 --- a/Hyperbar.Windows.Contextual/ContextualWidgetProvider.cs +++ b/Hyperbar.Windows.Contextual/ContextualWidgetProvider.cs @@ -1,4 +1,3 @@ -using Hyperbar.Extensions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/Hyperbar.Windows.Primary/PrimaryWidgetProvider.cs b/Hyperbar.Windows.Primary/PrimaryWidgetProvider.cs index e786666..ec42705 100644 --- a/Hyperbar.Windows.Primary/PrimaryWidgetProvider.cs +++ b/Hyperbar.Windows.Primary/PrimaryWidgetProvider.cs @@ -1,4 +1,3 @@ -using Hyperbar.Extensions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -10,7 +9,6 @@ public class PrimaryWidgetProvider : public void Create(HostBuilderContext comtext, IServiceCollection services) => services.AddConfiguration(comtext.Configuration.GetSection(nameof(PrimaryWidgetConfiguration)), PrimaryWidgetConfiguration.Defaults) - .AddTransient() - .AddTransient(provider => provider.GetRequiredService().Create()) + .AddHandler() .AddWidgetTemplate(); } \ No newline at end of file diff --git a/Hyperbar.Windows.Primary/PrimaryWidgetViewModel.cs b/Hyperbar.Windows.Primary/PrimaryWidgetViewModel.cs index 110e49b..dae45db 100644 --- a/Hyperbar.Windows.Primary/PrimaryWidgetViewModel.cs +++ b/Hyperbar.Windows.Primary/PrimaryWidgetViewModel.cs @@ -1,4 +1,4 @@ -namespace Hyperbar.Windows.Primary; + namespace Hyperbar.Windows.Primary; public class PrimaryWidgetViewModel : ObservableCollectionViewModel, diff --git a/Hyperbar.Windows.Primary/WidgetComponentMapping.cs b/Hyperbar.Windows.Primary/WidgetComponentMapping.cs new file mode 100644 index 0000000..020ac08 --- /dev/null +++ b/Hyperbar.Windows.Primary/WidgetComponentMapping.cs @@ -0,0 +1,20 @@ + +namespace Hyperbar.Windows.Primary; + +public class WidgetComponentMappingHandler(PrimaryWidgetConfiguration configuration, + IServiceFactory service, + IMediator mediator) : + IMappingHandler> +{ + public IEnumerable Handle() + { + foreach (IPrimaryCommandConfiguration item in configuration) + { + if (item is KeyAcceleratorCommandConfiguration keyAcceleratorCommand) + { + yield return service.Create(keyAcceleratorCommand.Icon, new Action(async () => + await mediator.SendAsync(new KeyAcceleratorCommand(VirtualKey.LeftWindows)))); + } + } + } +} \ No newline at end of file diff --git a/Hyperbar.Windows.Primary/WidgetComponentMappinglFactory.cs b/Hyperbar.Windows.Primary/WidgetComponentMappinglFactory.cs deleted file mode 100644 index 033561f..0000000 --- a/Hyperbar.Windows.Primary/WidgetComponentMappinglFactory.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace Hyperbar.Windows.Primary; - -public class WidgetComponentMappingFactory : - IMappingFactory> -{ - private readonly PrimaryWidgetConfiguration configuration; - private readonly IServiceFactory service; - private readonly IMediator mediator; - - public WidgetComponentMappingFactory(PrimaryWidgetConfiguration configuration, - IServiceFactory service, - IMediator mediator) - { - this.configuration = configuration; - this.service = service; - this.mediator = mediator; - } - - public IEnumerable Create() - { - foreach (IPrimaryCommandConfiguration item in configuration) - { - if (item is KeyAcceleratorCommandConfiguration keyAcceleratorCommand) - { - yield return service.Create(keyAcceleratorCommand.Icon, new Action(() => - mediator.Send(new KeyAcceleratorCommand(VirtualKey.LeftWindows)))); - } - } - } -} diff --git a/Hyperbar.Windows/App.xaml.cs b/Hyperbar.Windows/App.xaml.cs index 3134667..93e0121 100644 --- a/Hyperbar.Windows/App.xaml.cs +++ b/Hyperbar.Windows/App.xaml.cs @@ -1,11 +1,9 @@ -using Hyperbar.Extensions; -using Hyperbar.Widget.Contextual; +using Hyperbar.Widget.Contextual; using Hyperbar.Windows.Controls; using Hyperbar.Windows.Primary; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Options; using Microsoft.UI.Xaml; namespace Hyperbar.Windows; diff --git a/Hyperbar.Windows/Lifecycles/IServiceCollectionExtensions.cs b/Hyperbar.Windows/Lifecycles/IServiceCollectionExtensions.cs index 085fcdc..852c3eb 100644 --- a/Hyperbar.Windows/Lifecycles/IServiceCollectionExtensions.cs +++ b/Hyperbar.Windows/Lifecycles/IServiceCollectionExtensions.cs @@ -1,5 +1,4 @@ -using Hyperbar.Extensions; -using Hyperbar.Windows.Interop; +using Hyperbar.Windows.Interop; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -32,7 +31,7 @@ namespace Hyperbar.Windows isolatedServices.AddSingleton(); isolatedServices.AddSingleton(); - isolatedServices.AddHandler(); + isolatedServices.AddHandler(); isolatedServices.AddTransient(); isolatedServices.AddContentTemplate(); diff --git a/Hyperbar.Windows/Commands/KeyAcceleratorCommandHandler.cs b/Hyperbar.Windows/Mediators/KeyAcceleratorHandler.cs similarity index 69% rename from Hyperbar.Windows/Commands/KeyAcceleratorCommandHandler.cs rename to Hyperbar.Windows/Mediators/KeyAcceleratorHandler.cs index 548cc0a..f37088a 100644 --- a/Hyperbar.Windows/Commands/KeyAcceleratorCommandHandler.cs +++ b/Hyperbar.Windows/Mediators/KeyAcceleratorHandler.cs @@ -2,8 +2,8 @@ namespace Hyperbar.Windows; -public class KeyAcceleratorCommandHandler(IVirtualKeyboard virtualKeyboard) : - ICommandHandler +public class KeyAcceleratorHandler(IVirtualKeyboard virtualKeyboard) : + IRequestHandler { public ValueTask Handle(KeyAcceleratorCommand command, CancellationToken cancellationToken) diff --git a/Hyperbar/Commands/KeyAcceleratorCommand.cs b/Hyperbar/Commands/KeyAcceleratorCommand.cs index e01be53..ceb4d97 100644 --- a/Hyperbar/Commands/KeyAcceleratorCommand.cs +++ b/Hyperbar/Commands/KeyAcceleratorCommand.cs @@ -2,4 +2,4 @@ public record KeyAcceleratorCommand(VirtualKey Key, VirtualKey[]? Modifiers = null) : - ICommand; + IRequest; diff --git a/Hyperbar/Configuration/ConfigurationInitializer.cs b/Hyperbar/Configuration/ConfigurationInitializer.cs index d4f166d..246ae05 100644 --- a/Hyperbar/Configuration/ConfigurationInitializer.cs +++ b/Hyperbar/Configuration/ConfigurationInitializer.cs @@ -1,12 +1,27 @@ -namespace Hyperbar; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; +using System.Threading; + +namespace Hyperbar; + +public record ConfigurationChanged(TConfiguration Configuration) : INotification + where TConfiguration : + class; public class ConfigurationInitializer(DefaultConfiguration defaults, - IConfigurationWriter writer) : IInitializer + IConfigurationWriter writer, + IOptionsMonitor options, + IMediator mediator) : IInitializer where TConfiguration : class, new() { public Task InitializeAsync() { + options.OnChange(args => + { + mediator.PublishAsync(new ConfigurationChanged(args)); + }); + writer.Write(defaults.Configuration); return Task.CompletedTask; } diff --git a/Hyperbar/Extensions/IServiceCollectionExtensions.cs b/Hyperbar/Extensions/IServiceCollectionExtensions.cs index 89dd26c..a76cc09 100644 --- a/Hyperbar/Extensions/IServiceCollectionExtensions.cs +++ b/Hyperbar/Extensions/IServiceCollectionExtensions.cs @@ -6,14 +6,14 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; using System.Text.Json; -namespace Hyperbar.Extensions; +namespace Hyperbar; public static class IServiceCollectionExtensions { - public static IServiceCollection AddHandler(this IServiceCollection serviceCollection, + public static IServiceCollection AddHandler(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Transient) - where THandler : - notnull + where THandler : + IHandler { if (typeof(THandler).GetInterface(typeof(INotificationHandler<>).Name) is { } notificationContract) { @@ -21,13 +21,13 @@ public static class IServiceCollectionExtensions { Type notificationType = arguments[0]; - serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), ServiceLifetime.Singleton)); - serviceCollection.Add(new ServiceDescriptor(typeof(INotificationHandler<>).MakeGenericType(notificationType), + services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), ServiceLifetime.Singleton)); + services.Add(new ServiceDescriptor(typeof(INotificationHandler<>).MakeGenericType(notificationType), provider => provider.GetRequiredService(), lifetime)); } } - if (typeof(THandler).GetInterface(typeof(IRequestHandler<,>).Name) is { } requestContract) + if (typeof(THandler).GetInterface(typeof(IHandler<,>).Name) is { } requestContract) { if (requestContract.GetGenericArguments() is { Length: 2 } arguments) { @@ -36,8 +36,8 @@ public static class IServiceCollectionExtensions Type wrapperType = typeof(RequestClassHandlerWrapper<,>).MakeGenericType(requestType, responseType); - serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime)); - serviceCollection.Add(new ServiceDescriptor(wrapperType, + services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime)); + services.Add(new ServiceDescriptor(wrapperType, provider => provider.GetService()?.Create(wrapperType, provider.GetRequiredService(), provider.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType)))!, @@ -46,44 +46,19 @@ public static class IServiceCollectionExtensions } } - if (typeof(THandler).GetInterface(typeof(ICommandHandler<,>).Name) is { } commandContract) + if (typeof(THandler).GetInterface(typeof(IMappingHandler<,>).Name) is { } mappingContract) { - if (commandContract.GetGenericArguments() is { Length: 2 } arguments) + if (mappingContract.GetGenericArguments() is { Length: 2 } arguments) { Type requestType = arguments[0]; Type responseType = arguments[1]; - Type wrapperType = typeof(CommandClassHandlerWrapper<,>).MakeGenericType(requestType, responseType); - - serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime)); - serviceCollection.Add(new ServiceDescriptor(wrapperType, - provider => provider.GetService()?.Create(wrapperType, - provider.GetRequiredService(), - provider.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType)))!, - lifetime - )); + services.AddTransient(typeof(THandler)); + services.AddTransient(responseType, provider => ((dynamic)provider.GetRequiredService()).Handle()); } } - if (typeof(THandler).GetInterface(typeof(IQueryHandler<,>).Name) is { } queryContract) - { - if (queryContract.GetGenericArguments() is { Length: 2 } arguments) - { - Type requestType = arguments[0]; - Type responseType = arguments[1]; - - Type wrapperType = typeof(QueryClassHandlerWrapper<,>).MakeGenericType(requestType, responseType); - - serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime)); - serviceCollection.Add(new ServiceDescriptor(wrapperType, - provider => provider.GetService()?.Create(wrapperType, - provider.GetRequiredService(), - provider.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType)))!, - lifetime - )); - } - } - return serviceCollection; + return services; } public static IServiceCollection AddConfiguration(this IServiceCollection services, diff --git a/Hyperbar/Factories/IMappingFactory.cs b/Hyperbar/Factories/IMapping.cs similarity index 50% rename from Hyperbar/Factories/IMappingFactory.cs rename to Hyperbar/Factories/IMapping.cs index 93567e7..fb29cde 100644 --- a/Hyperbar/Factories/IMappingFactory.cs +++ b/Hyperbar/Factories/IMapping.cs @@ -1,6 +1,6 @@ namespace Hyperbar; -public interface IMappingFactory +public interface IMapping { TTo Create(); } diff --git a/Hyperbar/Mediators/CommandClassHandlerWrapper.cs b/Hyperbar/Mediators/CommandClassHandlerWrapper.cs deleted file mode 100644 index 2049992..0000000 --- a/Hyperbar/Mediators/CommandClassHandlerWrapper.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace Hyperbar; - -public class CommandClassHandlerWrapper - where TRequest : - class, - ICommand -{ - private readonly MessageHandlerDelegate handler; - - public CommandClassHandlerWrapper(ICommandHandler concreteHandler, - IEnumerable> pipelineBehaviours) - { - MessageHandlerDelegate handler = concreteHandler.Handle; - - foreach (IPipelineBehavior? pipeline in pipelineBehaviours.Reverse()) - { - MessageHandlerDelegate handlerCopy = handler; - IPipelineBehavior pipelineCopy = pipeline; - - handler = (TRequest message, CancellationToken cancellationToken) => - pipelineCopy.Handle(message, handlerCopy, cancellationToken); - } - - this.handler = handler; - } - - public ValueTask Handle(TRequest request, CancellationToken cancellationToken) => handler(request, cancellationToken); -} \ No newline at end of file diff --git a/Hyperbar/Mediators/ICommand.cs b/Hyperbar/Mediators/ICommand.cs deleted file mode 100644 index 605aacb..0000000 --- a/Hyperbar/Mediators/ICommand.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Hyperbar; - -public interface ICommand : ICommand; - -public interface ICommand : IMessage; \ No newline at end of file diff --git a/Hyperbar/Mediators/ICommandHandler.cs b/Hyperbar/Mediators/ICommandHandler.cs deleted file mode 100644 index 7ae513a..0000000 --- a/Hyperbar/Mediators/ICommandHandler.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Hyperbar; - -public interface ICommandHandler : ICommandHandler - where TCommand : - ICommand; - -public interface ICommandHandler - where TCommand : - ICommand -{ - ValueTask Handle(TCommand command, - CancellationToken cancellationToken); -} \ No newline at end of file diff --git a/Hyperbar/Mediators/IRequestHandler.cs b/Hyperbar/Mediators/IHandler.cs similarity index 55% rename from Hyperbar/Mediators/IRequestHandler.cs rename to Hyperbar/Mediators/IHandler.cs index 5bd8553..5420bf3 100644 --- a/Hyperbar/Mediators/IRequestHandler.cs +++ b/Hyperbar/Mediators/IHandler.cs @@ -1,6 +1,9 @@ namespace Hyperbar; -public interface IRequestHandler +public interface IHandler; + +public interface IHandler : + IHandler where TRequest : IRequest { @@ -8,8 +11,8 @@ public interface IRequestHandler CancellationToken cancellationToken); } -public interface IRequestHandler : - IRequestHandler +public interface IRequestHandler : + IHandler where TRequest : IRequest { diff --git a/Hyperbar/Mediators/IMappingHandler.cs b/Hyperbar/Mediators/IMappingHandler.cs new file mode 100644 index 0000000..c6045b6 --- /dev/null +++ b/Hyperbar/Mediators/IMappingHandler.cs @@ -0,0 +1,7 @@ +namespace Hyperbar; + +public interface IMappingHandler : + IHandler +{ + TTo Handle(); +} diff --git a/Hyperbar/Mediators/IMediator.cs b/Hyperbar/Mediators/IMediator.cs index 5c3eb7f..4ec6fd0 100644 --- a/Hyperbar/Mediators/IMediator.cs +++ b/Hyperbar/Mediators/IMediator.cs @@ -7,17 +7,9 @@ public interface IMediator where TNotification : INotification; - void Send(ICommand command); - ValueTask SendAsync(IRequest request, CancellationToken cancellationToken = default); - ValueTask SendAsync(ICommand command, - CancellationToken cancellationToken = default); - - ValueTask SendAsync(IQuery query, - CancellationToken cancellationToken = default); - ValueTask SendAsync(object message, CancellationToken cancellationToken = default); diff --git a/Hyperbar/Mediators/IQuery.cs b/Hyperbar/Mediators/IQuery.cs deleted file mode 100644 index e8c15ac..0000000 --- a/Hyperbar/Mediators/IQuery.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Hyperbar; - -public interface IQuery : IMessage; \ No newline at end of file diff --git a/Hyperbar/Mediators/IQueryHandler.cs b/Hyperbar/Mediators/IQueryHandler.cs deleted file mode 100644 index e2b49d4..0000000 --- a/Hyperbar/Mediators/IQueryHandler.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hyperbar; - -public interface IQueryHandler - where TQuery : - IQuery -{ - ValueTask Handle(TQuery query, - CancellationToken cancellationToken); -} \ No newline at end of file diff --git a/Hyperbar/Mediators/Map.cs b/Hyperbar/Mediators/Map.cs new file mode 100644 index 0000000..15d64d4 --- /dev/null +++ b/Hyperbar/Mediators/Map.cs @@ -0,0 +1,3 @@ +namespace Hyperbar; + +public class Map; diff --git a/Hyperbar/Mediators/Mediator.cs b/Hyperbar/Mediators/Mediator.cs index c58f399..ca996b5 100644 --- a/Hyperbar/Mediators/Mediator.cs +++ b/Hyperbar/Mediators/Mediator.cs @@ -50,45 +50,6 @@ public class Mediator(IServiceProvider provider) : return default; } - public ValueTask SendAsync(ICommand command, - CancellationToken cancellationToken = default) - { - dynamic? handler = provider.GetService(typeof(CommandClassHandlerWrapper<,>) - .MakeGenericType(command.GetType(), typeof(TResponse))); - - if (handler is not null) - { - return handler.Handle((dynamic)command, cancellationToken); - } - - return default; - } - - public void Send(ICommand command) - { - dynamic? handler = provider.GetService(typeof(CommandClassHandlerWrapper<,>) - .MakeGenericType(command.GetType(), typeof(TResponse))); - - if (handler is not null) - { - _ = handler.Handle((dynamic)command, default(CancellationToken)); - } - } - - public ValueTask SendAsync(IQuery query, - CancellationToken cancellationToken = default) - { - dynamic? handler = provider.GetService(typeof(QueryClassHandlerWrapper<,>) - .MakeGenericType(query.GetType(), typeof(TResponse))); - - if (handler is not null) - { - return handler.Handle((dynamic)query, cancellationToken); - } - - return default; - } - public ValueTask SendAsync(object message, CancellationToken cancellationToken = default) { @@ -108,37 +69,6 @@ public class Mediator(IServiceProvider provider) : } } - if (message.GetType().GetInterface(typeof(ICommand<>).Name) is { } commandType) - { - if (commandType.GetGenericArguments() is { Length: 1 } arguments) - { - Type responseType = arguments[0]; - - dynamic? handler = provider.GetService(typeof(CommandClassHandlerWrapper<,>) - .MakeGenericType(message.GetType(), responseType)); - - if (handler is not null) - { - return handler.Handle((dynamic)message, cancellationToken); - } - } - } - - if (message.GetType().GetInterface(typeof(IQuery<>).Name) is { } queryType) - { - if (queryType.GetGenericArguments() is { Length: 1 } arguments) - { - Type responseType = arguments[0]; - - dynamic? handler = provider.GetService(typeof(QueryClassHandlerWrapper<,>) - .MakeGenericType(message.GetType(), responseType)); - if (handler is not null) - { - return handler.Handle((dynamic)message, cancellationToken); - } - } - } - return default; } diff --git a/Hyperbar/Mediators/QueryClassHandlerWrapper.cs b/Hyperbar/Mediators/QueryClassHandlerWrapper.cs deleted file mode 100644 index 6eb6edc..0000000 --- a/Hyperbar/Mediators/QueryClassHandlerWrapper.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Hyperbar; - -public class QueryClassHandlerWrapper - where TRequest : - class, - IQuery -{ - private readonly MessageHandlerDelegate handler; - - public QueryClassHandlerWrapper(IQueryHandler concreteHandler, - IEnumerable> pipelineBehaviours) - { - MessageHandlerDelegate handler = concreteHandler.Handle; - - foreach (IPipelineBehavior? pipeline in pipelineBehaviours.Reverse()) - { - MessageHandlerDelegate handlerCopy = handler; - IPipelineBehavior pipelineCopy = pipeline; - - handler = (TRequest message, CancellationToken cancellationToken) => - pipelineCopy.Handle(message, handlerCopy, cancellationToken); - } - - this.handler = handler; - } - - public ValueTask Handle(TRequest request, CancellationToken cancellationToken) => - handler(request, cancellationToken); -} \ No newline at end of file diff --git a/Hyperbar/Mediators/RequestClassHandlerWrapper.cs b/Hyperbar/Mediators/RequestClassHandlerWrapper.cs index dc4f424..da5e11e 100644 --- a/Hyperbar/Mediators/RequestClassHandlerWrapper.cs +++ b/Hyperbar/Mediators/RequestClassHandlerWrapper.cs @@ -7,7 +7,7 @@ public class RequestClassHandlerWrapper { private readonly MessageHandlerDelegate handler; - public RequestClassHandlerWrapper(IRequestHandler concreteHandler, + public RequestClassHandlerWrapper(IHandler concreteHandler, IEnumerable> pipelineBehaviours) { MessageHandlerDelegate handler = concreteHandler.Handle;