diff --git a/Toolkit.Avalonia/ClassicDesktopStyleApplicationHandler.cs b/Toolkit.Avalonia/ClassicDesktopStyleApplicationHandler.cs index a2bd6d4..9a43001 100644 --- a/Toolkit.Avalonia/ClassicDesktopStyleApplicationHandler.cs +++ b/Toolkit.Avalonia/ClassicDesktopStyleApplicationHandler.cs @@ -6,9 +6,9 @@ using Toolkit.Foundation; namespace Toolkit.Avalonia; public class ClassicDesktopStyleApplicationHandler : - INotificationHandler> + IHandler> { - public Task Handle(NavigateEventArgs args) + public void Handle(NavigateEventArgs args) { if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime lifeTime) @@ -19,7 +19,5 @@ public class ClassicDesktopStyleApplicationHandler : window.DataContext = args.Content; } } - - return Task.CompletedTask; } } \ No newline at end of file diff --git a/Toolkit.Avalonia/ContentControlHandler.cs b/Toolkit.Avalonia/ContentControlHandler.cs index b14046f..c12ad16 100644 --- a/Toolkit.Avalonia/ContentControlHandler.cs +++ b/Toolkit.Avalonia/ContentControlHandler.cs @@ -5,9 +5,9 @@ using Toolkit.Foundation; namespace Toolkit.Avalonia; public class ContentControlHandler : - INotificationHandler> + IHandler> { - public async Task Handle(NavigateEventArgs args) + public void Handle(NavigateEventArgs args) { if (args.Region is ContentControl contentControl) { @@ -19,10 +19,10 @@ public class ContentControlHandler : control.Loaded -= HandleLoaded; if (control.DataContext is object content) { - if (content is IActivated activated) - { - await activated.OnActivated(); - } + //if (content is IActivated activated) + //{ + // await activated.OnActivated(); + //} } taskCompletionSource.SetResult(); @@ -33,10 +33,10 @@ public class ContentControlHandler : control.Unloaded -= HandleLoaded; if (control.DataContext is object content) { - if (content is IDeactivated deactivated) - { - await deactivated.OnDeactivated(); - } + //if (content is IDeactivated deactivated) + //{ + // await deactivated.OnDeactivated(); + //} if (content is IDisposable disposable) { @@ -52,8 +52,6 @@ public class ContentControlHandler : contentControl.Content = null; contentControl.Content = control; - - await taskCompletionSource.Task; } } } diff --git a/Toolkit.Avalonia/ContentDialogHandler.cs b/Toolkit.Avalonia/ContentDialogHandler.cs index 20d5b40..9187995 100644 --- a/Toolkit.Avalonia/ContentDialogHandler.cs +++ b/Toolkit.Avalonia/ContentDialogHandler.cs @@ -5,9 +5,9 @@ using Toolkit.UI.Controls.Avalonia; namespace Toolkit.Avalonia; public class ContentDialogHandler : - INotificationHandler> + IHandler> { - public async Task Handle(NavigateEventArgs args) + public async void Handle(NavigateEventArgs args) { if (args.Template is ContentDialog dialog) { @@ -76,41 +76,33 @@ public class ContentDialogHandler : deferral.Complete(); } - - if (!cancelled) - { - if (content is IDeactivating deactivating) - { - await deactivating.OnDeactivating(); - } - } } } } - async void HandleOpened(FluentAvalonia.UI.Controls.ContentDialog sender, + void HandleOpened(FluentAvalonia.UI.Controls.ContentDialog sender, EventArgs args) { dialog.Opened -= HandleOpened; if (dialog.DataContext is object content) { - if (content is IActivated activated) - { - await activated.OnActivated(); - } + //if (content is IActivated activated) + //{ + // activated.OnActivated(); + //} } } - async void HandleClosed(FluentAvalonia.UI.Controls.ContentDialog sender, + void HandleClosed(FluentAvalonia.UI.Controls.ContentDialog sender, FluentAvalonia.UI.Controls.ContentDialogClosedEventArgs args) { dialog.Closed -= HandleClosed; if (dialog.DataContext is object content) { - if (content is IDeactivated deactivated) - { - await deactivated.OnDeactivated(); - } + //if (content is IDeactivated deactivated) + //{ + // deactivated.OnDeactivated(); + //} } } diff --git a/Toolkit.Avalonia/ContentTemplate.cs b/Toolkit.Avalonia/ContentTemplate.cs index 0a39bcc..f762bce 100644 --- a/Toolkit.Avalonia/ContentTemplate.cs +++ b/Toolkit.Avalonia/ContentTemplate.cs @@ -30,10 +30,10 @@ public class ContentTemplate : control.Loaded -= HandleLoaded; if (control.DataContext is object content) { - if (content is IActivated activated) - { - await activated.OnActivated(); - } + //if (content is IActivated activated) + //{ + // await activated.OnActivated(); + //} } } @@ -41,10 +41,10 @@ public class ContentTemplate : { if (control.DataContext is object content) { - if (content is IActivated activated) - { - await activated.OnActivated(); - } + //if (content is IActivated activated) + //{ + // await activated.OnActivated(); + //} } } @@ -53,10 +53,10 @@ public class ContentTemplate : control.Unloaded -= HandleUnloaded; if (control.DataContext is object content) { - if (content is IDeactivated deactivated) - { - await deactivated.OnDeactivated(); - } + //if (content is IDeactivated deactivated) + //{ + // await deactivated.OnDeactivated(); + //} } } @@ -92,10 +92,10 @@ public class ContentTemplate : control.Loaded -= HandleLoaded; if (control.DataContext is object content) { - if (content is IActivated activated) - { - await activated.OnActivated(); - } + //if (content is IActivated activated) + //{ + // await activated.OnActivated(); + //} } } @@ -103,10 +103,10 @@ public class ContentTemplate : { if (control.DataContext is object content) { - if (content is IActivated activated) - { - await activated.OnActivated(); - } + //if (content is IActivated activated) + //{ + // await activated.OnActivated(); + //} } } @@ -115,10 +115,10 @@ public class ContentTemplate : control.Unloaded -= HandleUnloaded; if (control.DataContext is object content) { - if (content is IDeactivated deactivated) - { - await deactivated.OnDeactivated(); - } + //if (content is IDeactivated deactivated) + //{ + // await deactivated.OnDeactivated(); + //} } } diff --git a/Toolkit.Avalonia/FrameHandler.cs b/Toolkit.Avalonia/FrameHandler.cs index 147a146..6d0f4f1 100644 --- a/Toolkit.Avalonia/FrameHandler.cs +++ b/Toolkit.Avalonia/FrameHandler.cs @@ -8,10 +8,10 @@ using Toolkit.UI.Controls.Avalonia; namespace Toolkit.Avalonia; public class FrameHandler(ITransientNavigationStore navigationStore) : - INotificationHandler>, - INotificationHandler> + IHandler>, + IHandler> { - public Task Handle(NavigateEventArgs args) + public void Handle(NavigateEventArgs args) { if (args.Region is Frame frame) { @@ -32,10 +32,10 @@ public class FrameHandler(ITransientNavigationStore navigationStore) : sender.RemoveHandler(Frame.NavigatedFromEvent, HandleNavigatedFrom); if (sender.DataContext is object content) { - if (content is IDeactivated deactivated) - { - await deactivated.OnDeactivated(); - } + //if (content is IDeactivated deactivated) + //{ + // await deactivated.OnDeactivated(); + //} if (content is IDisposable disposable) { @@ -61,10 +61,10 @@ public class FrameHandler(ITransientNavigationStore navigationStore) : if (!args.Cancel) { - if (content is IDeactivating deactivating) - { - await deactivating.OnDeactivating(); - } + //if (content is IDeactivating deactivating) + //{ + // await deactivating.OnDeactivating(); + //} } } } @@ -72,10 +72,10 @@ public class FrameHandler(ITransientNavigationStore navigationStore) : sender.AddHandler(Frame.NavigatingFromEvent, HandleNavigatingFrom); if (sender.DataContext is object content) { - if (content is IActivated activated) - { - await activated.OnActivated(); - } + //if (content is IActivated activated) + //{ + // await activated.OnActivated(); + //} } async void HandleUnloaded(object? _, RoutedEventArgs __) @@ -87,10 +87,10 @@ public class FrameHandler(ITransientNavigationStore navigationStore) : if (control.DataContext is object content) { - if (content is IDeactivated deactivated) - { - await deactivated.OnDeactivated(); - } + //if (content is IDeactivated deactivated) + //{ + // await deactivated.OnDeactivated(); + //} if (content is IDisposable disposable) { @@ -206,17 +206,13 @@ public class FrameHandler(ITransientNavigationStore navigationStore) : } } } - - return Task.CompletedTask; } - public Task Handle(NavigateBackEventArgs args) + public void Handle(NavigateBackEventArgs args) { if (args.Context is Frame frame) { frame.GoBack(); } - - return Task.CompletedTask; } } \ No newline at end of file diff --git a/Toolkit.Avalonia/IServiceCollectionExtensions.cs b/Toolkit.Avalonia/IServiceCollectionExtensions.cs index 1f92754..21a7b65 100644 --- a/Toolkit.Avalonia/IServiceCollectionExtensions.cs +++ b/Toolkit.Avalonia/IServiceCollectionExtensions.cs @@ -26,19 +26,20 @@ public static class IServiceCollectionExtensions services.AddTransient(); services.AddTransient(); - services.AddHandler(); - services.AddHandler(); - services.AddHandler(); + services.AddAsyncHandler>, WriteClipboardHandler>(); + services.AddAsyncHandler, IReadOnlyCollection?, SelectFoldersHandler>(); + services.AddAsyncHandler, IReadOnlyCollection?, SelectFilesHandler>(); - services.AddHandler(nameof(IClassicDesktopStyleApplicationLifetime)); - services.AddHandler(nameof(ISingleViewApplicationLifetime)); - services.AddHandler(nameof(ContentControl)); + services.AddHandler, ClassicDesktopStyleApplicationHandler>(nameof(IClassicDesktopStyleApplicationLifetime)); + services.AddHandler, SingleViewApplicationHandler>(nameof(ISingleViewApplicationLifetime)); - services.AddHandler(nameof(Frame)); + services.AddHandler, ContentControlHandler>(nameof(ContentControl)); + + services.AddHandler, FrameHandler>(nameof(Frame)); services.TryAddSingleton, TransientNavigationStore>(); - services.AddHandler(nameof(ContentDialog)); - services.AddHandler(nameof(TaskDialog)); + services.AddHandler, ContentDialogHandler>(nameof(ContentDialog)); + services.AddHandler, TaskDialogHandler>(nameof(TaskDialog)); services.AddScoped(provider => new NavigationRegionCollection { @@ -64,18 +65,17 @@ public static class IServiceCollectionExtensions services.AddTransient(); - services.AddHandler(); - services.AddHandler(); - services.AddHandler(); + services.AddAsyncHandler>, WriteClipboardHandler>(); + services.AddAsyncHandler, IReadOnlyCollection?, SelectFoldersHandler>(); + services.AddAsyncHandler, IReadOnlyCollection?, SelectFilesHandler>(); - services.AddHandler(nameof(ContentControl)); + services.AddHandler, ContentControlHandler>(nameof(ContentControl)); - services.AddHandler(nameof(Frame)); + services.AddHandler, FrameHandler>(nameof(Frame)); + services.TryAddSingleton, TransientNavigationStore>(); - services.TryAddSingleton(provider.GetRequiredService>()); - - services.AddHandler(nameof(ContentDialog)); - services.AddHandler(nameof(TaskDialog)); + services.AddHandler, ContentDialogHandler>(nameof(ContentDialog)); + services.AddHandler, TaskDialogHandler>(nameof(TaskDialog)); }))); return services; diff --git a/Toolkit.Avalonia/SingleViewApplicationHandler.cs b/Toolkit.Avalonia/SingleViewApplicationHandler.cs index 0156dcf..d6b213a 100644 --- a/Toolkit.Avalonia/SingleViewApplicationHandler.cs +++ b/Toolkit.Avalonia/SingleViewApplicationHandler.cs @@ -6,9 +6,9 @@ using Toolkit.Foundation; namespace Toolkit.Avalonia; public class SingleViewApplicationHandler : - INotificationHandler> + IHandler> { - public Task Handle(NavigateEventArgs args) + public void Handle(NavigateEventArgs args) { if (Application.Current?.ApplicationLifetime is ISingleViewApplicationLifetime lifeTime) @@ -19,7 +19,5 @@ public class SingleViewApplicationHandler : control.DataContext = args.Content; } } - - return Task.CompletedTask; } } \ No newline at end of file diff --git a/Toolkit.Avalonia/TaskDialogHandler.cs b/Toolkit.Avalonia/TaskDialogHandler.cs index d528894..73a0d65 100644 --- a/Toolkit.Avalonia/TaskDialogHandler.cs +++ b/Toolkit.Avalonia/TaskDialogHandler.cs @@ -6,9 +6,9 @@ using Toolkit.UI.Controls.Avalonia; namespace Toolkit.Avalonia; public class TaskDialogHandler(ITopLevelProvider topLevelProvider) : - INotificationHandler> + IHandler> { - public async Task Handle(NavigateEventArgs args) + public async void Handle(NavigateEventArgs args) { if (args.Template is TaskDialog dialog) { @@ -45,10 +45,10 @@ public class TaskDialogHandler(ITopLevelProvider topLevelProvider) : if (!cancelled) { - if (content is IDeactivating deactivating) - { - await deactivating.OnDeactivating(); - } + //if (content is IDeactivating deactivating) + //{ + // await deactivating.OnDeactivating(); + //} } } } diff --git a/Toolkit.Foundation/Activation.cs b/Toolkit.Foundation/Activation.cs deleted file mode 100644 index ade3931..0000000 --- a/Toolkit.Foundation/Activation.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Toolkit.Foundation; - -public record Activation -{ - public static ActivationEventArgs As(TValue value) => new(value); - - public static ActivationEventArgs As() => - new(); -} \ No newline at end of file diff --git a/Toolkit.Foundation/ActivationBuilder.cs b/Toolkit.Foundation/ActivationBuilder.cs deleted file mode 100644 index cefef3e..0000000 --- a/Toolkit.Foundation/ActivationBuilder.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Toolkit.Foundation; - -public record ActivationBuilder(IActivation Value, object? Key = null); \ No newline at end of file diff --git a/Toolkit.Foundation/ActivationEventArgs.cs b/Toolkit.Foundation/ActivationEventArgs.cs deleted file mode 100644 index a13d81d..0000000 --- a/Toolkit.Foundation/ActivationEventArgs.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Toolkit.Foundation; - -public record ActivationEventArgs(TValue? Value = default) : - IActivation; - -public record ActivationEventArgs() : - IActivation; \ No newline at end of file diff --git a/Toolkit.Foundation/AppService.cs b/Toolkit.Foundation/AppService.cs index 5efce30..0ebf88e 100644 --- a/Toolkit.Foundation/AppService.cs +++ b/Toolkit.Foundation/AppService.cs @@ -1,10 +1,11 @@ -using Microsoft.Extensions.Hosting; +using CommunityToolkit.Mvvm.Messaging; +using Microsoft.Extensions.Hosting; namespace Toolkit.Foundation; public class AppService(IEnumerable initializations, IEnumerable asyncInitializations, - IPublisher publisher) : + IMessenger messenger) : IHostedService { public async Task StartAsync(CancellationToken cancellationToken) @@ -18,8 +19,8 @@ public class AppService(IEnumerable initializations, { await initialization.Initialize(); } - - publisher.Publish(); + + messenger.Send(); } public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; diff --git a/Toolkit.Foundation/AsyncHandlerInitialization.cs b/Toolkit.Foundation/AsyncHandlerInitialization.cs new file mode 100644 index 0000000..2ba37f9 --- /dev/null +++ b/Toolkit.Foundation/AsyncHandlerInitialization.cs @@ -0,0 +1,20 @@ +using CommunityToolkit.Mvvm.Messaging; +using Microsoft.Extensions.DependencyInjection; + +namespace Toolkit.Foundation; + +public class AsyncHandlerInitialization(IServiceProvider provider) : + IInitialization where THandler : class, IAsyncHandler + where TMessage : class +{ + public void Initialize() => WeakReferenceMessenger.Default.Register>(provider, + async (provider, args) => args.Reply(await provider.GetRequiredService().Handle(args.Message, args.CancellationToken))); +} + +public class AsyncHandlerInitialization(IServiceProvider provider) : + IInitialization where THandler : class, IAsyncHandler + where TMessage : class +{ + public void Initialize() => WeakReferenceMessenger.Default.Register>(provider, + async (provider, args) => await provider.GetRequiredService().Handle(args.Message, args.CancellationToken)); +} \ No newline at end of file diff --git a/Toolkit.Foundation/AsyncResponseEventArgs.cs b/Toolkit.Foundation/AsyncResponseEventArgs.cs new file mode 100644 index 0000000..559812d --- /dev/null +++ b/Toolkit.Foundation/AsyncResponseEventArgs.cs @@ -0,0 +1,11 @@ +using CommunityToolkit.Mvvm.Messaging.Messages; + +namespace Toolkit.Foundation; + +public class AsyncResponseEventArgs : + AsyncRequestMessage +{ + public TMessage? Message { get; set; } + + public CancellationToken CancellationToken { get; set; } +} \ No newline at end of file diff --git a/Toolkit.Foundation/CommandValueViewModel.cs b/Toolkit.Foundation/CommandValueViewModel.cs index fd2e5c7..050411a 100644 --- a/Toolkit.Foundation/CommandValueViewModel.cs +++ b/Toolkit.Foundation/CommandValueViewModel.cs @@ -1,14 +1,13 @@ using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.Mvvm.Messaging; namespace Toolkit.Foundation; public partial class CommandValueViewModel(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer) : - Observable(provider, factory, mediator, publisher, subscriber, disposer) + Observable(provider, factory, messenger, disposer) where TValue : notnull { public IRelayCommand InvokeCommand => diff --git a/Toolkit.Foundation/CommandViewModel.cs b/Toolkit.Foundation/CommandViewModel.cs index 2b384b5..111faef 100644 --- a/Toolkit.Foundation/CommandViewModel.cs +++ b/Toolkit.Foundation/CommandViewModel.cs @@ -1,14 +1,13 @@ using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.Mvvm.Messaging; namespace Toolkit.Foundation; public partial class CommandViewModel(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer) : - Observable(provider, factory, mediator, publisher, subscriber, disposer) + Observable(provider, factory, messenger, disposer) { public IRelayCommand InvokeCommand => new AsyncRelayCommand(InvokeAsync); diff --git a/Toolkit.Foundation/ComponentBuilder.cs b/Toolkit.Foundation/ComponentBuilder.cs index 78791a3..0f242bd 100644 --- a/Toolkit.Foundation/ComponentBuilder.cs +++ b/Toolkit.Foundation/ComponentBuilder.cs @@ -26,12 +26,12 @@ public class ComponentBuilder : services.AddSingleton(); - services.AddScoped(); + //services.AddScoped(); - services.AddTransient(); - services.AddScoped(); - services.AddTransient(); - services.AddTransient(); + //services.AddTransient(); + //services.AddScoped(); + //services.AddTransient(); + //services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -42,8 +42,8 @@ public class ComponentBuilder : services.AddScoped(); services.AddTransient(); - services.AddHandler(); - services.AddHandler(); + //services.AddHandler(); + //services.AddHandler(); }); } diff --git a/Toolkit.Foundation/ComponentFactory.cs b/Toolkit.Foundation/ComponentFactory.cs index 77221a2..5d01187 100644 --- a/Toolkit.Foundation/ComponentFactory.cs +++ b/Toolkit.Foundation/ComponentFactory.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using CommunityToolkit.Mvvm.Messaging; +using Microsoft.Extensions.DependencyInjection; namespace Toolkit.Foundation; @@ -28,7 +29,7 @@ public class ComponentFactory(IServiceProvider provider, provider.GetRequiredService()); services.AddTransient(_ => - provider.GetRequiredService>()); + provider.GetRequiredService>()); services.AddTransient(_ => provider.GetRequiredService>()); diff --git a/Toolkit.Foundation/ComponentInitializer.cs b/Toolkit.Foundation/ComponentInitializer.cs index 2ee2b9c..970d277 100644 --- a/Toolkit.Foundation/ComponentInitializer.cs +++ b/Toolkit.Foundation/ComponentInitializer.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using CommunityToolkit.Mvvm.Messaging; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace Toolkit.Foundation; @@ -18,7 +19,7 @@ public class ComponentInitializer(IEnumerable components, builder.AddServices(services => { services.AddTransient(_ => - provider.GetRequiredService>()); + provider.GetRequiredService>()); services.AddTransient(_ => provider.GetRequiredService>()); diff --git a/Toolkit.Foundation/ConfigurationChangedHandler.cs b/Toolkit.Foundation/ConfigurationChangedHandler.cs index 1c343bc..5419287 100644 --- a/Toolkit.Foundation/ConfigurationChangedHandler.cs +++ b/Toolkit.Foundation/ConfigurationChangedHandler.cs @@ -1,11 +1,11 @@ namespace Toolkit.Foundation; public class ConfigurationChangedHandler(ConfigurationValue configurationValue) : - INotificationHandler> + IHandler> where TValue : class, new() { - public Task Handle(ChangedEventArgs args) + public void Handle(ChangedEventArgs args) { if (args.Sender is TConfiguration configuration) { @@ -13,7 +13,5 @@ public class ConfigurationChangedHandler(ConfigurationVa { } } - - return Task.CompletedTask; } } \ No newline at end of file diff --git a/Toolkit.Foundation/ConfigurationInitializer.cs b/Toolkit.Foundation/ConfigurationInitializer.cs index c9389f8..d2fa61c 100644 --- a/Toolkit.Foundation/ConfigurationInitializer.cs +++ b/Toolkit.Foundation/ConfigurationInitializer.cs @@ -1,9 +1,11 @@ -namespace Toolkit.Foundation; +using CommunityToolkit.Mvvm.Messaging; + +namespace Toolkit.Foundation; public class ConfigurationInitializer(IConfigurationReader reader, IConfigurationWriter writer, IConfigurationFactory factory, - IPublisher publisher) : + IMessenger messenger) : IConfigurationInitializer, IInitialization where TConfiguration : @@ -20,6 +22,6 @@ public class ConfigurationInitializer(IConfigurationReader(configuration)); + messenger.Send(new ActivatedEventArgs(configuration)); } } \ No newline at end of file diff --git a/Toolkit.Foundation/ConfigurationMonitor.cs b/Toolkit.Foundation/ConfigurationMonitor.cs index ccbb85b..ce43cc8 100644 --- a/Toolkit.Foundation/ConfigurationMonitor.cs +++ b/Toolkit.Foundation/ConfigurationMonitor.cs @@ -1,12 +1,13 @@ -using Microsoft.Extensions.DependencyInjection; +using CommunityToolkit.Mvvm.Messaging; +using Microsoft.Extensions.DependencyInjection; namespace Toolkit.Foundation; public class ConfigurationMonitor(string section, IConfigurationCache cache, IConfigurationFile file, - IServiceProvider serviceProvider, - IPublisher publisher) : + IServiceProvider provider, + IMessenger messenger) : IConfigurationMonitor where TConfiguration : class @@ -18,11 +19,11 @@ public class ConfigurationMonitor(string section, void ChangedHandler(object sender, FileSystemEventArgs args) { - if (serviceProvider.GetRequiredKeyedService>(section) is + if (provider.GetRequiredKeyedService>(section) is IConfigurationDescriptor configuration) { cache.Remove(section); - publisher.PublishUI(new ChangedEventArgs(configuration.Value)); + messenger.Send(new ChangedEventArgs(configuration.Value)); } } diff --git a/Toolkit.Foundation/ConfigurationValueViewModel.cs b/Toolkit.Foundation/ConfigurationValueViewModel.cs index 1935d47..fceeb33 100644 --- a/Toolkit.Foundation/ConfigurationValueViewModel.cs +++ b/Toolkit.Foundation/ConfigurationValueViewModel.cs @@ -1,39 +1,39 @@  +using CommunityToolkit.Mvvm.Messaging; + namespace Toolkit.Foundation; public partial class ConfigurationValueViewModel(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer, TConfiguration configuration, IWritableConfiguration writer, Func read, Action write) : - Observable(provider, factory, mediator, publisher, subscriber, disposer), - INotificationHandler> + Observable(provider, factory, messenger, disposer), + IHandler> where TConfiguration : class { - public async Task Handle(ChangedEventArgs args) + public void Handle(ChangedEventArgs args) { if (args.Sender is TConfiguration configuration) { - await Task.Run(() => Value = read(configuration)); + Value = read(configuration); } } - public override async Task OnActivated() + protected override void OnActivated() { - await Task.Run(() => Value = read(configuration)); - await base.OnActivated(); + Value = read(configuration); + base.OnActivated(); } - protected override async void OnChanged(TValue? value) + protected override void OnChanged(TValue? value) { - if (IsActivated) + if (IsActive) { - await Task.Run(() => writer.Write(args => write(value, args))); + writer.Write(args => write(value, args)); } base.OnChanged(value); @@ -42,7 +42,7 @@ public partial class ConfigurationValueViewModel(IServic public partial class ConfigurationValueViewModel : ObservableCollection, - INotificationHandler> + IHandler> where TConfiguration : class where TItem : notnull, IDisposable @@ -51,17 +51,16 @@ public partial class ConfigurationValueViewModel private readonly Func read; private readonly Action write; private readonly IWritableConfiguration writer; + public ConfigurationValueViewModel(IServiceProvider provider, - IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IServiceFactory factory, + IMessenger messenger, IDisposer disposer, TConfiguration configuration, IWritableConfiguration writer, Func read, Action write, - TValue? value = default) : base(provider, factory, mediator, publisher, subscriber, disposer, value) + TValue? value = default) : base(provider, factory, messenger, disposer, value) { this.configuration = configuration; this.writer = writer; @@ -73,16 +72,14 @@ public partial class ConfigurationValueViewModel public ConfigurationValueViewModel(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer, IEnumerable items, TConfiguration configuration, IWritableConfiguration writer, Func read, Action write, - TValue? value = default) : base(provider, factory, mediator, publisher, subscriber, disposer, items, value) + TValue? value = default) : base(provider, factory, messenger, disposer, items, value) { this.configuration = configuration; this.writer = writer; @@ -92,25 +89,25 @@ public partial class ConfigurationValueViewModel Value = value; } - public async Task Handle(ChangedEventArgs args) + public void Handle(ChangedEventArgs args) { if (args.Sender is TConfiguration configuration) { - await Task.Run(() => Value = read(configuration)); + Value = read(configuration); } } - public override async Task OnActivated() + protected override void OnActivated() { - await Task.Run(() => Value = read(configuration)); - await base.OnActivated(); + Value = read(configuration); + base.OnActivated(); } - protected override async void OnChanged(TValue? value) + protected override void OnChanged(TValue? value) { - if (IsActivated) + if (IsActive) { - await Task.Run(() => writer.Write(args => write(value, args))); + writer.Write(args => write(value, args)); } base.OnChanged(value); diff --git a/Toolkit.Foundation/DefaultHostBuilder.cs b/Toolkit.Foundation/DefaultHostBuilder.cs index c2f431d..082fca9 100644 --- a/Toolkit.Foundation/DefaultHostBuilder.cs +++ b/Toolkit.Foundation/DefaultHostBuilder.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Configuration; +using CommunityToolkit.Mvvm.Messaging; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -20,19 +20,20 @@ public class DefaultHostBuilder : ComponentHostCollection>(); services.AddSingleton(); + services.AddSingleton(_ => WeakReferenceMessenger.Default); - services.AddScoped(); + //services.AddScoped(); - services.AddTransient(); - services.AddScoped(); - services.AddTransient(); - services.AddTransient(); + //services.AddTransient(); + //services.AddScoped(); + //services.AddTransient(); + //services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddScoped>(provider => - new ProxyService(provider.GetRequiredService())); + services.AddScoped>(provider => + new ProxyService(provider.GetRequiredService())); services.AddScoped>(provider => new ProxyService(provider.GetRequiredService())); @@ -56,10 +57,10 @@ public class DefaultHostBuilder : services.AddTransient(); services.AddTransient(); - services.AddHandler(); - services.AddHandler(); + //services.AddHandler(); + //services.AddHandler(); - services.AddInitialization(); + //services.AddInitialization(); services.AddHostedService(); }); } diff --git a/Toolkit.Foundation/HandlerInitialization.cs b/Toolkit.Foundation/HandlerInitialization.cs new file mode 100644 index 0000000..885afe5 --- /dev/null +++ b/Toolkit.Foundation/HandlerInitialization.cs @@ -0,0 +1,20 @@ +using CommunityToolkit.Mvvm.Messaging; +using Microsoft.Extensions.DependencyInjection; + +namespace Toolkit.Foundation; + +public class HandlerInitialization(IServiceProvider provider) : + IInitialization where THandler : class, IHandler + where TMessage : class +{ + public void Initialize() => WeakReferenceMessenger.Default.Register>(provider, + (provider, args) => args.Reply(provider.GetRequiredService().Handle(args.Message))); +} + +public class HandlerInitialization(string key, IServiceProvider provider) : + IInitialization where THandler : class, IHandler + where TMessage : class +{ + public void Initialize() => WeakReferenceMessenger.Default.Register(provider, key, + (provider, args) => provider.GetRequiredKeyedService(key).Handle(args)); +} \ No newline at end of file diff --git a/Toolkit.Foundation/HandlerProvider.cs b/Toolkit.Foundation/HandlerProvider.cs deleted file mode 100644 index e0ce08f..0000000 --- a/Toolkit.Foundation/HandlerProvider.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Toolkit.Foundation; - -public class HandlerProvider(SubscriptionCollection subscriptions) : - IHandlerProvider -{ - public IEnumerable Get(object key) - { - var d = subscriptions; - if (subscriptions.TryGetValue(key, out List? subscribers)) - { - foreach (WeakReference weakRef in subscribers.ToArray()) - { - object? target = weakRef.Target; - if (target != null) - { - yield return target; - } - else - { - subscribers.Remove(weakRef); - } - } - } - } -} \ No newline at end of file diff --git a/Toolkit.Foundation/HandlerWrapper.cs b/Toolkit.Foundation/HandlerWrapper.cs deleted file mode 100644 index ffd1d13..0000000 --- a/Toolkit.Foundation/HandlerWrapper.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Toolkit.Foundation; - -public class HandlerWrapper(IHandler handler, - IEnumerable> pipelineBehaviours) - where TRequest : notnull -{ - private readonly IEnumerable> pipelineBehaviours = - pipelineBehaviours.Reverse(); - - public async Task Handle(TRequest request, - CancellationToken cancellationToken) - { - HandlerDelegate currentHandler = handler.Handle; - foreach (IPipelineBehaviour behaviour in pipelineBehaviours) - { - HandlerDelegate previousHandler = currentHandler; - currentHandler = async (args, token) => - { - return await behaviour.Handle(args, previousHandler, token); - }; - } - - return await currentHandler(request, cancellationToken); - } -} \ No newline at end of file diff --git a/Toolkit.Foundation/IActivated.cs b/Toolkit.Foundation/IActivated.cs deleted file mode 100644 index d335a1e..0000000 --- a/Toolkit.Foundation/IActivated.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Toolkit.Foundation; - -public interface IActivated -{ - Task OnActivated(); -} \ No newline at end of file diff --git a/Toolkit.Foundation/IActivation.cs b/Toolkit.Foundation/IActivation.cs deleted file mode 100644 index 26c23c8..0000000 --- a/Toolkit.Foundation/IActivation.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Toolkit.Foundation; - -public interface IActivation; \ No newline at end of file diff --git a/Toolkit.Foundation/IAsyncHandler.cs b/Toolkit.Foundation/IAsyncHandler.cs new file mode 100644 index 0000000..5665c37 --- /dev/null +++ b/Toolkit.Foundation/IAsyncHandler.cs @@ -0,0 +1,13 @@ +namespace Toolkit.Foundation; + +public interface IAsyncHandler : + IHandler +{ + Task Handle(TMessage args, CancellationToken cancellationToken = default); +} + +public interface IAsyncHandler : + IHandler +{ + Task Handle(TMessage args, CancellationToken cancellationToken = default); +} diff --git a/Toolkit.Foundation/IDeactivated.cs b/Toolkit.Foundation/IDeactivated.cs deleted file mode 100644 index 84bbeb4..0000000 --- a/Toolkit.Foundation/IDeactivated.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Toolkit.Foundation; - -public interface IDeactivated -{ - Task OnDeactivated(); -} \ No newline at end of file diff --git a/Toolkit.Foundation/IDeactivating.cs b/Toolkit.Foundation/IDeactivating.cs deleted file mode 100644 index 4b58970..0000000 --- a/Toolkit.Foundation/IDeactivating.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Toolkit.Foundation; - -public interface IDeactivating -{ - Task OnDeactivating(); -} \ No newline at end of file diff --git a/Toolkit.Foundation/IHandler.cs b/Toolkit.Foundation/IHandler.cs index 2263715..7811218 100644 --- a/Toolkit.Foundation/IHandler.cs +++ b/Toolkit.Foundation/IHandler.cs @@ -2,12 +2,14 @@ public interface IHandler; -public interface IHandler : +public interface IHandler : IHandler { - Task Handle(TRequest args, - CancellationToken cancellationToken); + void Handle(TMessage args); } -public interface IHandler : - IHandler; \ No newline at end of file +public interface IHandler : + IHandler +{ + TResponse Handle(TMessage args); +} \ No newline at end of file diff --git a/Toolkit.Foundation/IHandlerProvider.cs b/Toolkit.Foundation/IHandlerProvider.cs deleted file mode 100644 index 6ce7f05..0000000 --- a/Toolkit.Foundation/IHandlerProvider.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Toolkit.Foundation; - -public interface IHandlerProvider -{ - IEnumerable Get(object key); -} \ No newline at end of file diff --git a/Toolkit.Foundation/IHostBuilderExtension.cs b/Toolkit.Foundation/IHostBuilderExtension.cs index 8aa74f2..7756323 100644 --- a/Toolkit.Foundation/IHostBuilderExtension.cs +++ b/Toolkit.Foundation/IHostBuilderExtension.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Configuration; +using CommunityToolkit.Mvvm.Messaging; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.FileProviders; @@ -163,7 +164,7 @@ public static class IHostBuilderExtension new ConfigurationInitializer(provider.GetRequiredKeyedService>(section), provider.GetRequiredKeyedService>(section), provider.GetRequiredKeyedService>(section), - provider.GetRequiredService())); + provider.GetRequiredService())); services.AddTransient, ConfigurationInitializer>(provider => provider.GetRequiredService().Create>(section)); @@ -188,7 +189,7 @@ public static class IHostBuilderExtension provider.GetRequiredKeyedService(section), provider.GetRequiredKeyedService>(section), provider.GetRequiredService(), - provider.GetRequiredService())); + provider.GetRequiredService())); } }); diff --git a/Toolkit.Foundation/IMediator.cs b/Toolkit.Foundation/IMediator.cs deleted file mode 100644 index 6a8cdc3..0000000 --- a/Toolkit.Foundation/IMediator.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Toolkit.Foundation; - -public interface IMediator -{ - Task Handle(Type responseType, - object message, - object? key = null, - CancellationToken cancellationToken = default); - - Task Handle(TMessage message, - object? key = null, - CancellationToken cancellationToken = default) - where TMessage : notnull; - - IAsyncEnumerable HandleAsyncMany(Type responseType, - object message, - object? key = null, - CancellationToken cancellationToken = default); - - IAsyncEnumerable HandleAsyncMany(TMessage message, - object? key = null, - CancellationToken cancellationToken = default) - where TMessage : notnull; - - Task> HandleMany(TMessage message, - object? key = null, - CancellationToken cancellationToken = default) - where TMessage : notnull; -} \ No newline at end of file diff --git a/Toolkit.Foundation/IMediatorRequired.cs b/Toolkit.Foundation/IMediatorRequired.cs deleted file mode 100644 index 0ab9d7e..0000000 --- a/Toolkit.Foundation/IMediatorRequired.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Toolkit.Foundation; - -public interface IMediatorRequired -{ - IMediator Mediator { get; } -} \ No newline at end of file diff --git a/Toolkit.Foundation/IMessage.cs b/Toolkit.Foundation/IMessage.cs deleted file mode 100644 index 211c872..0000000 --- a/Toolkit.Foundation/IMessage.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Toolkit.Foundation; - -public interface IMessage; \ No newline at end of file diff --git a/Toolkit.Foundation/IMessengerExtensions.cs b/Toolkit.Foundation/IMessengerExtensions.cs new file mode 100644 index 0000000..32c5b7e --- /dev/null +++ b/Toolkit.Foundation/IMessengerExtensions.cs @@ -0,0 +1,19 @@ +using CommunityToolkit.Mvvm.Messaging; + +namespace Toolkit.Foundation; + +public static class IMessengerExtensions +{ + public static TResponse Send(this IMessenger messenger) + where TMessage : class, new() + { + ResponseEventArgs args = messenger.Send(new ResponseEventArgs { Message = new TMessage() }); + return args.Response; + } + + public static void Send(this IMessenger messenger, string key) + where TMessage : class, new() => messenger.Send(new TMessage(), key); + + public static async Task SendAsync(this IMessenger messenger) + where TMessage : class, new() => await messenger.Send(new AsyncResponseEventArgs { Message = new TMessage() }); +} diff --git a/Toolkit.Foundation/IMessengerRequired.cs b/Toolkit.Foundation/IMessengerRequired.cs new file mode 100644 index 0000000..f1f7aef --- /dev/null +++ b/Toolkit.Foundation/IMessengerRequired.cs @@ -0,0 +1,8 @@ +using CommunityToolkit.Mvvm.Messaging; + +namespace Toolkit.Foundation; + +public interface IMessengerRequired +{ + IMessenger Messenger { get; } +} \ No newline at end of file diff --git a/Toolkit.Foundation/INotificationHandler.cs b/Toolkit.Foundation/INotificationHandler.cs deleted file mode 100644 index 6d52db3..0000000 --- a/Toolkit.Foundation/INotificationHandler.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Toolkit.Foundation; - -public interface INotificationHandler : - IHandler -{ - Task Handle(TMessage args); -} \ No newline at end of file diff --git a/Toolkit.Foundation/IObservableViewModel.cs b/Toolkit.Foundation/IObservableViewModel.cs index 333fa16..f2d8ce5 100644 --- a/Toolkit.Foundation/IObservableViewModel.cs +++ b/Toolkit.Foundation/IObservableViewModel.cs @@ -1,11 +1,13 @@ -namespace Toolkit.Foundation; +using CommunityToolkit.Mvvm.Messaging; + +namespace Toolkit.Foundation; public interface IObservableViewModel : IDisposable { public IDisposer Disposer { get; } - public IPublisher Publisher { get; } + public IMessenger Messenger { get; } public IServiceFactory Factory { get; } diff --git a/Toolkit.Foundation/IPipelineBehaviour.cs b/Toolkit.Foundation/IPipelineBehaviour.cs deleted file mode 100644 index 9f4999e..0000000 --- a/Toolkit.Foundation/IPipelineBehaviour.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Toolkit.Foundation; - -public interface IPipelineBehaviour -{ - Task Handle(TMessage message, - HandlerDelegate next, - CancellationToken cancellationToken = default); -} - -public interface IPipelineBehaviour -{ - Task Handle(TMessage message, - NotificationHandlerDelegate next, - CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/Toolkit.Foundation/IPublisher.cs b/Toolkit.Foundation/IPublisher.cs deleted file mode 100644 index 88d1411..0000000 --- a/Toolkit.Foundation/IPublisher.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace Toolkit.Foundation; - -public interface IPublisher -{ - void Publish(object? key = null) - where TMessage : new(); - - void Publish(TMessage message) - where TMessage : notnull; - - void Publish(TMessage message, - object? key = null) - where TMessage : notnull; - - void Publish(object message, - Func, Task> marshal, - object? key = null); - - void Publish() - where TMessage : new(); - - void Publish(object message); - - void PublishUI(TMessage message, - object? key = null) where TMessage : notnull; - - void PublishUI(object? key = null) - where TMessage : new(); - - void PublishUI(TMessage message) - where TMessage : notnull; - - void PublishUI(object message); - - void PublishUI() - where TMessage : new(); -} \ No newline at end of file diff --git a/Toolkit.Foundation/IPublisherRequired.cs b/Toolkit.Foundation/IPublisherRequired.cs deleted file mode 100644 index 20212c1..0000000 --- a/Toolkit.Foundation/IPublisherRequired.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Toolkit.Foundation; - -public interface IPublisherRequired -{ - IPublisher Publisher { get; } -} \ No newline at end of file diff --git a/Toolkit.Foundation/IServiceCollectionExtensions.cs b/Toolkit.Foundation/IServiceCollectionExtensions.cs index c0c8c56..fe30f9a 100644 --- a/Toolkit.Foundation/IServiceCollectionExtensions.cs +++ b/Toolkit.Foundation/IServiceCollectionExtensions.cs @@ -38,61 +38,59 @@ public static class IServiceCollectionExtensions return services; } - public static IServiceCollection AddHandler(this IServiceCollection services, - string key) - where THandler : IHandler + public static IServiceCollection AddHandler(this IServiceCollection services, + ServiceLifetime lifetime = ServiceLifetime.Transient) + where THandler : class, IHandler + where TMessage : class { - return AddHandler(services, ServiceLifetime.Transient, key); + services.Add(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime)); + services.AddInitialization>(); + + return services; } - public static IServiceCollection AddHandler(this IServiceCollection services, + public static IServiceCollection AddAsyncHandler(this IServiceCollection services, + ServiceLifetime lifetime = ServiceLifetime.Transient) + where THandler : class, IAsyncHandler + where TMessage : class + { + services.Add(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime)); + services.AddInitialization>(); + + return services; + } + + public static IServiceCollection AddAsyncHandler(this IServiceCollection services, + ServiceLifetime lifetime = ServiceLifetime.Transient) + where THandler : class, IAsyncHandler + where TMessage : class + { + services.Add(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime)); + services.AddInitialization>(); + + return services; + } + + public static IServiceCollection AddHandler(this IServiceCollection services, + string key) + where THandler : class, IHandler + where TMessage : class => AddHandler(services, ServiceLifetime.Transient, key); + + public static IServiceCollection AddHandler(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Transient, string? key = null) - where THandler : IHandler + where THandler : class, IHandler + where TMessage : class { - if (typeof(THandler).GetInterfaces() is Type[] handlerTypes) + if (key is { Length: > 0}) { - foreach (Type handlerType in handlerTypes) - { - if (handlerType.Name == typeof(INotificationHandler<>).Name && - handlerType.GetGenericArguments() is { Length: 1 } notificationHandlerArguments) - { - Type notificationType = notificationHandlerArguments[0]; - Type wrapperType = typeof(NotificationHandlerWrapper<>).MakeGenericType(notificationType); - - string preferredKey = $"{(key is not null ? $"{key}:" : "")}{notificationType}"; - - services.Add(new ServiceDescriptor(typeof(INotificationHandler<>) - .MakeGenericType(notificationType), preferredKey, typeof(THandler), lifetime)); - - services.Add(new ServiceDescriptor(wrapperType, preferredKey, (provider, registeredKey) => - provider.GetService()?.Create(wrapperType, - provider.GetRequiredKeyedService(typeof(INotificationHandler<>).MakeGenericType(notificationType), registeredKey), - provider.GetServices(typeof(IPipelineBehaviour<>) - .MakeGenericType(notificationType)))!, lifetime)); - } - - if (handlerType.Name == typeof(IHandler<,>).Name && - handlerType.GetGenericArguments() is { Length: 2 } handlerArguments) - { - Type requestType = handlerArguments[0]; - Type responseType = handlerArguments[1]; - - Type wrapperType = typeof(HandlerWrapper<,>).MakeGenericType(requestType, responseType); - string preferredKey = $"{(key is not null ? $"{key}:" : "")}{wrapperType}"; - - services.Add(new ServiceDescriptor(typeof(THandler), preferredKey, - typeof(THandler), lifetime)); - - services.Add(new ServiceDescriptor(wrapperType, preferredKey, (provider, actualKey) => - provider.GetService()?.Create(wrapperType, - provider.GetRequiredKeyedService(preferredKey), - provider.GetServices(typeof(IPipelineBehaviour<,>) - .MakeGenericType(requestType, responseType)))!, lifetime)); - } - } - - return services; + services.Add(new ServiceDescriptor(typeof(THandler), key, typeof(THandler), lifetime)); + services.AddInitialization>(key); + } + else + { + services.Add(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime)); + services.AddInitialization>(); } return services; @@ -106,6 +104,15 @@ public static class IServiceCollectionExtensions return services; } + public static IServiceCollection AddInitialization(this IServiceCollection services, + params object[] parameters) + where TInitialization : class, + IInitialization + { + services.AddTransient(provider => provider.GetRequiredService().Create(parameters)); + return services; + } + public static IServiceCollection AddRange(this IServiceCollection services, IServiceCollection fromServices) { diff --git a/Toolkit.Foundation/ISubscriber.cs b/Toolkit.Foundation/ISubscriber.cs deleted file mode 100644 index aada57f..0000000 --- a/Toolkit.Foundation/ISubscriber.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Toolkit.Foundation; - -public interface ISubscriber -{ - void Subscribe(object subscriber); - - void Unsubscribe(object subscriber); -} \ No newline at end of file diff --git a/Toolkit.Foundation/ISubscriberRequired.cs b/Toolkit.Foundation/ISubscriberRequired.cs deleted file mode 100644 index 7a41b2b..0000000 --- a/Toolkit.Foundation/ISubscriberRequired.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Toolkit.Foundation; - -public interface ISubscriberRequired -{ - ISubscriber Subscription { get; } -} \ No newline at end of file diff --git a/Toolkit.Foundation/Mediator.cs b/Toolkit.Foundation/Mediator.cs deleted file mode 100644 index b3731a1..0000000 --- a/Toolkit.Foundation/Mediator.cs +++ /dev/null @@ -1,165 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using System.Reflection; -using System.Runtime.CompilerServices; - -namespace Toolkit.Foundation; - -public class Mediator(IHandlerProvider handlerProvider, - IServiceProvider provider) : - IMediator -{ - public async Task Handle(TMessage message, - object? key = null, - CancellationToken cancellationToken = default) - where TMessage : notnull - { - Type messageType = message.GetType(); - Type handlerType = typeof(HandlerWrapper<,>).MakeGenericType(messageType, typeof(TResponse)); - key = $"{(key is not null ? $"{key}:" : "")}{handlerType}"; - - List handlers = GetHandlers(message, handlerType, key); - foreach (object? handler in handlers) - { - MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", [message.GetType(), typeof(CancellationToken)]); - if (handleMethod is not null) - { - return await (Task)handleMethod.Invoke(handler, [message, cancellationToken])!; - } - } - - return default; - } - - public async Task Handle(Type responseType, - object message, - object? key = null, - CancellationToken cancellationToken = default) - { - Type messageType = message.GetType(); - Type handlerType = typeof(HandlerWrapper<,>).MakeGenericType(message.GetType(), responseType); - key = $"{(key is not null ? $"{key}:" : "")}{handlerType}"; - - List handlers = GetHandlers(message, handlerType, key); - foreach (object? handler in handlers) - { - MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", - [messageType, typeof(CancellationToken)]); - - if (handleMethod is not null) - { - dynamic task = handleMethod.Invoke(handler, [message, cancellationToken])!; - await task; - - return task.Result; - } - } - - return default; - } - - public async IAsyncEnumerable HandleAsyncMany(Type responseType, - object message, - object? key = null, - [EnumeratorCancellation] CancellationToken cancellationToken = default) - { - Type messageType = message.GetType(); - Type handlerType = typeof(HandlerWrapper<,>).MakeGenericType(message.GetType(), responseType); - key = $"{(key is not null ? $"{key}:" : "")}{handlerType}"; - - List handlers = GetHandlers(message, handlerType, key); - foreach (object? handler in handlers) - { - MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", - [messageType, typeof(CancellationToken)]); - - if (handleMethod is not null) - { - yield return await (Task)handleMethod.Invoke(handler, [message, cancellationToken])!; - } - } - } - - public async IAsyncEnumerable HandleAsyncMany(TMessage message, - object? key = null, - [EnumeratorCancellation] CancellationToken cancellationToken = default) - where TMessage : notnull - { - Type messageType = message.GetType(); - Type handlerType = typeof(HandlerWrapper<,>).MakeGenericType(messageType, typeof(TResponse)); - key = $"{(key is not null ? $"{key}:" : "")}{handlerType}"; - - List handlers = GetHandlers(message, handlerType, key); - foreach (object? handler in handlers) - { - MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", [message.GetType(), typeof(CancellationToken)]); - if (handleMethod is not null) - { - yield return await (Task)handleMethod.Invoke(handler, [message, cancellationToken])!; - } - } - } - - public async Task> HandleMany(Type responseType, - object message, - object? key = null, - CancellationToken cancellationToken = default) - { - List responses = []; - await foreach (object? response in HandleAsyncMany(responseType, message, key, cancellationToken)) - { - responses.Add(response); - } - - return responses; - } - - public async Task> HandleMany(TMessage message, - object? key = null, - CancellationToken cancellationToken = default) - where TMessage : notnull - { - List responses = []; - await foreach (TResponse? response in HandleAsyncMany(message, key, cancellationToken)) - { - responses.Add(response); - } - - return responses; - } - private List GetHandlers(object message, - Type handlerWrapperType, - object? key) - { - Type messageType = message.GetType(); - Dictionary> handlers = []; - - void AddHandlers(IEnumerable newHandlers) - { - foreach (object? handler in newHandlers) - { - if (handler == null) continue; - - Type serviceType = handler.GetType(); - if (!handlers.TryGetValue(serviceType, out List? handlerList)) - { - handlerList = []; - handlers.Add(serviceType, handlerList); - } - - handlerList.Add(handler); - } - } - - IEnumerable keyedServices = key is not null ? provider.GetKeyedServices(handlerWrapperType, key) : - provider.GetServices(handlerWrapperType); - AddHandlers(keyedServices); - - if (key is not null) - { - IEnumerable additionalHandlers = handlerProvider.Get(key); - AddHandlers(additionalHandlers); - } - - return handlers.SelectMany(entry => entry.Value).ToList(); - } -} \ No newline at end of file diff --git a/Toolkit.Foundation/NavigateBackHandler.cs b/Toolkit.Foundation/NavigateBackHandler.cs index 69534a4..643c1d8 100644 --- a/Toolkit.Foundation/NavigateBackHandler.cs +++ b/Toolkit.Foundation/NavigateBackHandler.cs @@ -3,9 +3,9 @@ namespace Toolkit.Foundation; public class NavigateBackHandler(IComponentScopeProvider provider) : - INotificationHandler + IHandler { - public Task Handle(NavigateBackEventArgs args) + public void Handle(NavigateBackEventArgs args) { if (provider.Get(args.Scope ?? "Root") is ComponentScopeDescriptor descriptor) @@ -16,7 +16,5 @@ public class NavigateBackHandler(IComponentScopeProvider provider) : navigationScope.Back(args.Context); } } - - return Task.CompletedTask; } } \ No newline at end of file diff --git a/Toolkit.Foundation/NavigateHandler.cs b/Toolkit.Foundation/NavigateHandler.cs index b1eec14..252767a 100644 --- a/Toolkit.Foundation/NavigateHandler.cs +++ b/Toolkit.Foundation/NavigateHandler.cs @@ -4,9 +4,9 @@ namespace Toolkit.Foundation; public class NavigateHandler(NamedComponent scope, IComponentScopeProvider componentScopeProvider) : - INotificationHandler + IHandler { - public Task Handle(NavigateEventArgs args) + public void Handle(NavigateEventArgs args) { INavigation? navigation = null; if (args.Scope is "self" || args.Scope is "new") @@ -34,7 +34,5 @@ public class NavigateHandler(NamedComponent scope, navigation?.Navigate(args.Route, args.Sender, args.Region, args.Navigated, args.Parameters); - - return Task.CompletedTask; } } \ No newline at end of file diff --git a/Toolkit.Foundation/Navigation.cs b/Toolkit.Foundation/Navigation.cs index fb473e8..e5d05be 100644 --- a/Toolkit.Foundation/Navigation.cs +++ b/Toolkit.Foundation/Navigation.cs @@ -1,11 +1,12 @@ -using Microsoft.Extensions.DependencyInjection; +using CommunityToolkit.Mvvm.Messaging; +using Microsoft.Extensions.DependencyInjection; namespace Toolkit.Foundation; public class Navigation(IServiceProvider provider, INavigationRegionProvider navigationRegionProvider, IContentFactory contentFactory, - IPublisher publisher) : + IMessenger messenger) : INavigation { public void Navigate(string route, @@ -71,7 +72,7 @@ public class Navigation(IServiceProvider provider, if (Activator.CreateInstance(navigateEventType, [region, template, content, sender, parameters]) is object navigateEvent) { - publisher.Publish(navigateEvent, navigationType.Name); + messenger.Send(navigateEvent, navigationType.Name); if (currentSegmentIndex == segmentCount) { navigated?.Invoke(this, EventArgs.Empty); @@ -97,7 +98,7 @@ public class Navigation(IServiceProvider provider, Type navigateType = typeof(NavigateBackEventArgs<>).MakeGenericType(navigationType); if (Activator.CreateInstance(navigateType, [region]) is object navigate) { - publisher.Publish(navigate, navigationType.Name); + messenger.Send(navigate, navigationType.Name); } } } diff --git a/Toolkit.Foundation/NotificationHandlerDelegate.cs b/Toolkit.Foundation/NotificationHandlerDelegate.cs deleted file mode 100644 index f0e6031..0000000 --- a/Toolkit.Foundation/NotificationHandlerDelegate.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Toolkit.Foundation; - -public delegate Task NotificationHandlerDelegate(TMessage message); \ No newline at end of file diff --git a/Toolkit.Foundation/NotificationHandlerWrapper.cs b/Toolkit.Foundation/NotificationHandlerWrapper.cs deleted file mode 100644 index e012ab3..0000000 --- a/Toolkit.Foundation/NotificationHandlerWrapper.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Toolkit.Foundation; - -public class NotificationHandlerWrapper(INotificationHandler handler, - IEnumerable> pipelineBehaviours) -{ - private readonly IEnumerable> pipelineBehaviours = - pipelineBehaviours.Reverse(); - - public async Task Handle(TMessage message) - { - NotificationHandlerDelegate currentHandler = handler.Handle; - foreach (IPipelineBehaviour behaviour in pipelineBehaviours) - { - NotificationHandlerDelegate previousHandler = currentHandler; - currentHandler = async (args) => - { - await behaviour.Handle(args, previousHandler); - }; - } - - await currentHandler(message); - } -} \ No newline at end of file diff --git a/Toolkit.Foundation/Observable.cs b/Toolkit.Foundation/Observable.cs index cfd0abe..2a51894 100644 --- a/Toolkit.Foundation/Observable.cs +++ b/Toolkit.Foundation/Observable.cs @@ -1,55 +1,30 @@ using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Messaging; namespace Toolkit.Foundation; public partial class Observable(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer) : - ObservableObject, + ObservableRecipient, IObservableViewModel, IActivityIndicator, - IInitialization, - IActivated, - IDeactivating, - IDeactivated, IDisposable, IServiceProviderRequired, IServiceFactoryRequired, - IMediatorRequired, - IPublisherRequired, + IMessengerRequired, IDisposerRequired { private readonly Dictionary trackedProperties = []; - [ObservableProperty] - private bool isActivated; - - [ObservableProperty] - private bool isActive; - - [ObservableProperty] - private bool isInitialized; - public IDisposer Disposer { get; } = disposer; public IServiceFactory Factory { get; } = factory; - public IMediator Mediator { get; } = mediator; - public IServiceProvider Provider { get; } = provider; - public IPublisher Publisher { get; } = publisher; - - public ISubscriber Subscriber { get; } = subscriber; - - public virtual Task OnActivated() - { - IsActivated = true; - return Task.CompletedTask; - } + public IMessenger Messenger { get; } = messenger; public void Commit() { @@ -59,37 +34,12 @@ public partial class Observable(IServiceProvider provider, } } - public virtual Task OnDeactivated() - { - IsActivated = false; - return Task.CompletedTask; - } - - public virtual Task OnDeactivating() => - Task.CompletedTask; - public virtual void Dispose() { GC.SuppressFinalize(this); Disposer.Dispose(this); } - public virtual void OnInitialize() - { - } - - public virtual void Initialize() - { - if (IsInitialized) - { - return; - } - - IsInitialized = true; - Subscriber.Subscribe(this); - OnInitialize(); - } - public void Revert() { foreach (object trackedProperty in trackedProperties.Values) @@ -116,11 +66,9 @@ public partial class Observable : public Observable(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer, - TValue? value = default) : base(provider, factory, mediator, publisher, subscriber, disposer) + TValue? value = default) : base(provider, factory, messenger, disposer) { Value = value; } @@ -143,12 +91,10 @@ public partial class Observable : public Observable(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer, TKey key, - TValue? value = default) : base(provider, factory, mediator, publisher, subscriber, disposer) + TValue? value = default) : base(provider, factory, messenger, disposer) { Key = key; Value = value; diff --git a/Toolkit.Foundation/ObservableCollection.cs b/Toolkit.Foundation/ObservableCollection.cs index 5453673..aeb48ea 100644 --- a/Toolkit.Foundation/ObservableCollection.cs +++ b/Toolkit.Foundation/ObservableCollection.cs @@ -1,5 +1,5 @@ using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.Mvvm.Messaging; using Microsoft.Extensions.DependencyInjection; using System.Collections; using System.Collections.Specialized; @@ -8,12 +8,8 @@ using System.Reactive.Disposables; namespace Toolkit.Foundation; public partial class ObservableCollection : - ObservableObject, + ObservableRecipient, IObservableCollectionViewModel, - IInitialization, - IActivated, - IDeactivating, - IDeactivated, IList, IList, IReadOnlyList, @@ -21,17 +17,15 @@ public partial class ObservableCollection : ICollectionSynchronization, IServiceProviderRequired, IServiceFactoryRequired, - IMediatorRequired, - IPublisherRequired, + IMessengerRequired, IDisposerRequired, - INotificationHandler>, - INotificationHandler>, - INotificationHandler>, - INotificationHandler>, - INotificationHandler>, - INotificationHandler>, - INotificationHandler>, - INotificationHandler> + IRecipient>, + IRecipient>, + IRecipient>, + IRecipient>, + IRecipient>, + IRecipient>, + IRecipient> where TViewModel : notnull, IDisposable { @@ -39,8 +33,6 @@ public partial class ObservableCollection : private readonly IDispatcher dispatcher; - private readonly Queue pendingEvents = []; - private readonly Dictionary trackedProperties = []; [ObservableProperty] @@ -49,28 +41,20 @@ public partial class ObservableCollection : private Func? defaultSelectionFactory; [ObservableProperty] - private bool isActivated; + private bool initialized; private bool isClearing; - [ObservableProperty] - private bool isInitialized; - [ObservableProperty] private TViewModel? selectedItem; public ObservableCollection(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, - IDisposer disposer) + IMessenger messenger, + IDisposer disposer) : base(messenger) { Provider = provider; Factory = factory; - Mediator = mediator; - Publisher = publisher; - Subscriber = subscriber; Disposer = disposer; dispatcher = Provider.GetRequiredService(); @@ -79,17 +63,12 @@ public partial class ObservableCollection : public ObservableCollection(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer, - IEnumerable items) + IEnumerable items) : base(messenger) { Provider = provider; Factory = factory; - Mediator = mediator; - Publisher = publisher; - Subscriber = subscriber; Disposer = disposer; dispatcher = Provider.GetRequiredService(); @@ -105,21 +84,12 @@ public partial class ObservableCollection : public IServiceFactory Factory { get; private set; } bool IList.IsFixedSize => false; - bool ICollection.IsReadOnly => false; - bool IList.IsReadOnly => false; - bool ICollection.IsSynchronized => false; - - public IMediator Mediator { get; } - + public new IMessenger Messenger { get; private set; } public IServiceProvider Provider { get; private set; } - public IPublisher Publisher { get; private set; } - - public ISubscriber Subscriber { get; } - object ICollection.SyncRoot => this; public TViewModel this[int index] @@ -147,29 +117,6 @@ public partial class ObservableCollection : } } - public void Activate(Func activateDelegate, - bool reset = false) - { - if (reset) - { - Clear(); - } - - ActivationBuilder builder = activateDelegate.Invoke(); - Publisher.Publish(builder.Value, builder.Key); - } - - public void Activate(bool reset = false) - { - if (reset) - { - Clear(); - } - - ActivationBuilder builder = ActivationBuilder(); - Publisher.PublishUI(builder.Value, builder.Key); - } - public TViewModel Add(params object?[] parameters) where T : TViewModel { @@ -289,129 +236,6 @@ public partial class ObservableCollection : IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)collection).GetEnumerator(); - public Task Handle(RemoveEventArgs args) - { - if (IsActivated) - { - foreach (TViewModel item in this.ToList()) - { - if (args.Sender is not null && args.Sender.Equals(item)) - { - Remove(item); - } - } - } - else - { - pendingEvents.Enqueue(args); - } - - return Task.CompletedTask; - } - - public Task Handle(CreateEventArgs args) - { - if (IsActivated) - { - if (args.Sender is TViewModel item) - { - Add(item); - } - } - else - { - pendingEvents.Enqueue(args); - } - - return Task.CompletedTask; - } - - public Task Handle(InsertEventArgs args) - { - if (IsActivated) - { - if (args.Sender is TViewModel item) - { - Insert(args.Index, item); - } - } - else - { - pendingEvents.Enqueue(args); - } - - return Task.CompletedTask; - } - - public Task Handle(MoveToEventArgs args) - { - if (IsActivated) - { - Move(args.OldIndex, args.NewIndex); - } - else - { - pendingEvents.Enqueue(args); - } - - return Task.CompletedTask; - } - - public Task Handle(MoveEventArgs args) - { - if (IsActivated) - { - if (args.Sender is TViewModel item) - { - Move(args.Index, item); - } - } - else - { - pendingEvents.Enqueue(args); - } - - return Task.CompletedTask; - } - - public Task Handle(ReplaceEventArgs args) - { - if (IsActivated) - { - if (args.Sender is TViewModel item) - { - Replace(args.Index, item); - } - } - else - { - pendingEvents.Enqueue(args); - } - - return Task.CompletedTask; - } - - public Task Handle(RemoveAtEventArgs args) - { - if (IsActivated) - { - int index = args.Index; - if (index >= 0 && index <= Count - 1) - { - RemoveAt(index); - } - } - else - { - pendingEvents.Enqueue(args); - } - - return Task.CompletedTask; - } - - public Task Handle(SelectionEventArgs args) => - Task.CompletedTask; - public int IndexOf(TViewModel item) => collection.IndexOf(item); @@ -419,22 +243,6 @@ public partial class ObservableCollection : IsCompatibleObject(value) ? IndexOf((TViewModel)value!) : -1; - [RelayCommand] - public virtual void Initialize() - { - if (IsInitialized) - { - return; - } - - IsInitialized = true; - Subscriber.Subscribe(this); - - OnInitialize(); - - Activate(); - } - public TViewModel Insert(int index = 0, params object?[] parameters) where T : @@ -519,31 +327,67 @@ public partial class ObservableCollection : return true; } - public virtual Task OnActivated() - { - IsActivated = true; - while (pendingEvents.Count > 0) - { - object current = pendingEvents.Dequeue(); - Handle((dynamic)current); - } - - return Task.CompletedTask; - } - - public virtual Task OnDeactivated() - { - IsActivated = false; - return Task.CompletedTask; - } - - public virtual Task OnDeactivating() => - Task.CompletedTask; - public virtual void OnInitialize() { } + public void Receive(RemoveEventArgs args) + { + foreach (TViewModel item in this.ToList()) + { + if (args.Sender is not null && args.Sender.Equals(item)) + { + Remove(item); + } + } + } + + public void Receive(CreateEventArgs args) + { + if (args.Sender is TViewModel item) + { + Add(item); + } + } + + public void Receive(InsertEventArgs args) + { + if (args.Sender is TViewModel item) + { + Insert(args.Index, item); + } + } + + public void Receive(MoveToEventArgs args) + { + Move(args.OldIndex, args.NewIndex); + } + + public void Receive(MoveEventArgs args) + { + if (args.Sender is TViewModel item) + { + Move(args.Index, item); + } + } + + public void Receive(ReplaceEventArgs args) + { + if (args.Sender is TViewModel item) + { + Replace(args.Index, item); + } + } + + public void Receive(RemoveAtEventArgs args) + { + int index = args.Index; + if (index >= 0 && index <= Count - 1) + { + RemoveAt(index); + } + } + public bool Remove(TViewModel item) { int index = collection.IndexOf(item); @@ -637,7 +481,7 @@ public partial class ObservableCollection : } } - public void SetSource(IList source, Func? defaultSelectionFactory) + public void SetSource(IList source, Func? defaultSelectionFactory) { foreach (TViewModel item in source) { @@ -666,9 +510,6 @@ public partial class ObservableCollection : } } - protected virtual ActivationBuilder ActivationBuilder() => - new(new ActivationEventArgs()); - protected virtual void ClearItems() => collection.Clear(); @@ -692,10 +533,6 @@ public partial class ObservableCollection : collection.Insert(index > Count ? Count : index, item); } - protected virtual void OnSelectedItemChanged() - { - } - protected virtual void RemoveItem(int index) => collection.RemoveAt(index); @@ -711,18 +548,6 @@ public partial class ObservableCollection : CollectionChanged?.Invoke(this, args); } - partial void OnIsActivatedChanged(bool value) - { - if (value) - { - while (pendingEvents.Count > 0) - { - object current = pendingEvents.Dequeue(); - Handle((dynamic)current); - } - } - } - partial void OnSelectedItemChanged(TViewModel? oldValue, TViewModel? newValue) { if (oldValue is ISelectable oldSelection) @@ -735,8 +560,7 @@ public partial class ObservableCollection : newSelection.IsSelected = true; } - Publisher.Publish(Selection.As(SelectedItem)); - OnSelectedItemChanged(); + Messenger.Send(Selection.As(SelectedItem)); } private void SourceCollectionChanged(object? sender, @@ -785,6 +609,7 @@ public partial class ObservableCollection : break; } } + private void UpdateSelection(TViewModel item) { if (item is ISelectable newSelection) @@ -809,32 +634,27 @@ public partial class ObservableCollection : [ObservableProperty] private TValue? value; - public ObservableCollection(IServiceProvider provider, + public ObservableCollection(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer, - TValue? value = default) : base(provider, factory, mediator, publisher, subscriber, disposer) + TValue? value = default) : base(provider, factory, messenger, disposer) { Value = value; } public ObservableCollection(IServiceProvider provider, - IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, - IDisposer disposer, + IServiceFactory factory, + IMessenger messenger, + IDisposer disposer, IEnumerable items, - TValue? value = default) : base(provider, factory, mediator, publisher, subscriber, disposer, items) + TValue? value = default) : base(provider, factory, messenger, disposer, items) { Value = value; } protected virtual void OnChanged(TValue? value) { - } partial void OnValueChanged(TValue? value) => OnChanged(value); @@ -852,12 +672,10 @@ public partial class ObservableCollection : public ObservableCollection(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer, TKey key, - TValue? value = default) : base(provider, factory, mediator, publisher, subscriber, disposer) + TValue? value = default) : base(provider, factory, messenger, disposer) { Key = key; Value = value; @@ -865,13 +683,11 @@ public partial class ObservableCollection : public ObservableCollection(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer, IEnumerable items, TKey key, - TValue? value = default) : base(provider, factory, mediator, publisher, subscriber, disposer, items) + TValue? value = default) : base(provider, factory, messenger, disposer, items) { Key = key; Value = value; @@ -883,20 +699,18 @@ public class ObservableCollection : { public ObservableCollection(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, - IDisposer disposer) : base(provider, factory, mediator, publisher, subscriber, disposer) + IMessenger messenger, + IDisposer disposer) : base(provider, factory, messenger, disposer) { + } public ObservableCollection(IServiceProvider provider, IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer, - IEnumerable items) : base(provider, factory, mediator, publisher, subscriber, disposer, items) + IEnumerable items) : base(provider, factory, messenger, disposer, items) { + } } \ No newline at end of file diff --git a/Toolkit.Foundation/Publisher.cs b/Toolkit.Foundation/Publisher.cs deleted file mode 100644 index 0020d12..0000000 --- a/Toolkit.Foundation/Publisher.cs +++ /dev/null @@ -1,88 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using System.Reflection; - -namespace Toolkit.Foundation; - -public class Publisher(IHandlerProvider handlerProvider, - IServiceFactory serviceFactory, - IServiceProvider serviceProvider, - IDispatcher dispatcher) : - IPublisher -{ - public void Publish(object? key = null) - where TMessage : new() => - Publish(serviceFactory.Create() ?? new TMessage(), async args => await args(), key); - - public void Publish(TMessage message) - where TMessage : notnull => - Publish(message, async args => await args(), null); - - public void Publish(TMessage message, - object? key = null) - where TMessage : notnull => - Publish(message, async args => await args(), key); - - public void Publish(object message, - Func, Task> marshal, - object? key = null) - { - Type notificationType = message.GetType(); - Type handlerType = typeof(NotificationHandlerWrapper<>) - .MakeGenericType(notificationType); - - key = $"{(key is not null ? $"{key}:" : "")}{notificationType}"; - - List handlers = []; - foreach (object? handler in handlerProvider.Get(key)) - { - handlers.Add(handler); - } - - foreach (object? handler in serviceProvider.GetKeyedServices(handlerType, key)) - { - handlers.Add(handler); - } - - foreach (object? handler in handlers) - { - if (handler is not null) - { - MethodInfo? handleMethod = handler.GetType().GetMethod("Handle", - [notificationType]); - - if (handleMethod is not null) - { - marshal(() => (Task)handleMethod.Invoke(handler, new object[] - { message })!); - } - } - } - } - - public void Publish(object message) => Publish(message, - async args => await args(), null); - - public void Publish() - where TMessage : new() => - Publish(new TMessage(), async args => await args(), null); - - public void PublishUI(object? key = null) - where TMessage : new() => - Publish(new TMessage(), args => dispatcher.Invoke(async () => await args()), key); - - public void PublishUI(TMessage message) - where TMessage : notnull => - Publish(message, args => dispatcher.Invoke(async () => await args()), null); - - public void PublishUI(TMessage message, - object? key = null) - where TMessage : notnull => - Publish(message, args => dispatcher.Invoke(async () => await args()), key); - - public void PublishUI() - where TMessage : new() => - Publish(new TMessage(), args => dispatcher.Invoke(async () => await args()), null); - - public void PublishUI(object message) => Publish(message, args => - dispatcher.Invoke(async () => await args()), null); -} \ No newline at end of file diff --git a/Toolkit.Foundation/ResponseEventArgs.cs b/Toolkit.Foundation/ResponseEventArgs.cs new file mode 100644 index 0000000..f9ab71a --- /dev/null +++ b/Toolkit.Foundation/ResponseEventArgs.cs @@ -0,0 +1,9 @@ +using CommunityToolkit.Mvvm.Messaging.Messages; + +namespace Toolkit.Foundation; + +public class ResponseEventArgs : + RequestMessage +{ + public TMessage? Message { get; set; } +} \ No newline at end of file diff --git a/Toolkit.Foundation/SelectFilesHandler.cs b/Toolkit.Foundation/SelectFilesHandler.cs index d45cca0..dcff4be 100644 --- a/Toolkit.Foundation/SelectFilesHandler.cs +++ b/Toolkit.Foundation/SelectFilesHandler.cs @@ -1,7 +1,7 @@ namespace Toolkit.Foundation; public class SelectFilesHandler(IFileProvider fileProvider) : - IHandler, IReadOnlyCollection?> + IAsyncHandler, IReadOnlyCollection?> { public async Task?> Handle(SelectionEventArgs args, CancellationToken cancellationToken) diff --git a/Toolkit.Foundation/SelectFoldersHandler.cs b/Toolkit.Foundation/SelectFoldersHandler.cs index 34d415f..7718dd0 100644 --- a/Toolkit.Foundation/SelectFoldersHandler.cs +++ b/Toolkit.Foundation/SelectFoldersHandler.cs @@ -2,10 +2,10 @@ public class SelectFoldersHandler(IFolderProvider folderProvider) : - IHandler, IReadOnlyCollection?> + IAsyncHandler, IReadOnlyCollection?> { - public async Task?> Handle(SelectionEventArgs args, - CancellationToken cancellationToken) + public async Task?> Handle(SelectionEventArgs args, + CancellationToken cancellationToken = default) { if (args.Sender is FolderFilter filter) { diff --git a/Toolkit.Foundation/Subscriber.cs b/Toolkit.Foundation/Subscriber.cs deleted file mode 100644 index 88c772f..0000000 --- a/Toolkit.Foundation/Subscriber.cs +++ /dev/null @@ -1,165 +0,0 @@ -using System.Reactive.Disposables; - -namespace Toolkit.Foundation; - -public class Subscriber(SubscriptionCollection subscriptions, - IDisposer disposer) : - ISubscriber -{ - public void Subscribe(object subscriber) - { - IDictionary> subscribers = GetSubscriptionKeys(subscriber); - - foreach (Type handlerType in GetHandlerInterfaces(subscriber.GetType())) - { - if (handlerType.Name == typeof(INotificationHandler<>).Name && - handlerType.GetGenericArguments() is { Length: 1 } notificationHandlerArguments) - { - Type notificationType = notificationHandlerArguments[0]; - AddSubscriptions(subscriber, subscribers, notificationType); - } - - if (handlerType.Name == typeof(IHandler<,>).Name && - handlerType.GetGenericArguments() is { Length: 2 } handlerArguments) - { - Type requestType = handlerArguments[0]; - Type responseType = handlerArguments[1]; - Type wrapperType = typeof(HandlerWrapper<,>).MakeGenericType(requestType, responseType); - - AddSubscriptions(subscriber, subscribers, wrapperType); - } - } - } - - public void Unsubscribe(object subscriber) - { - IDictionary> subscribers = GetSubscriptionKeys(subscriber); - - foreach (Type handlerType in GetHandlerInterfaces(subscriber.GetType())) - { - if (handlerType.Name == typeof(INotificationHandler<>).Name && - handlerType.GetGenericArguments() is { Length: 1 } notificationHandlerArguments) - { - Type notificationType = notificationHandlerArguments[0]; - RemoveSubscriptions(subscriber, subscribers, notificationType); - } - - if (handlerType.Name == typeof(IHandler<,>).Name && - handlerType.GetGenericArguments() is { Length: 2 } handlerArguments) - { - Type requestType = handlerArguments[0]; - Type responseType = handlerArguments[1]; - Type wrapperType = typeof(HandlerWrapper<,>).MakeGenericType(requestType, responseType); - - RemoveSubscriptions(subscriber, subscribers, wrapperType); - } - } - } - - private void AddOrUpdateSubscription(object subscriber, - string preferredKey) - { - subscriptions.AddOrUpdate(preferredKey, _ => new List { new(subscriber) }, (_, collection) => - { - collection.Add(new WeakReference(subscriber)); - return collection; - }); - - disposer.Add(subscriber, Disposable.Create(() => { - - RemoveSubscription(subscriber, preferredKey); - - })); - } - - private void AddSubscriptions(object subscriber, - IDictionary> subscribers, - Type handlerType) - { - if (subscribers.TryGetValue(handlerType, out List? keys)) - { - foreach (object key in keys) - { - string preferredKey = $"{(key is not null ? $"{key}:" : "")}{handlerType}"; - AddOrUpdateSubscription(subscriber, preferredKey); - } - } - else - { - string preferredKey = $"{handlerType}"; - AddOrUpdateSubscription(subscriber, preferredKey); - } - } - - private IEnumerable GetHandlerInterfaces(Type handlerType) => - handlerType.GetInterfaces().Where(interfaceType => - { - Type? definition = interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : null; - return definition == typeof(INotificationHandler<>) || - definition == typeof(IHandler<>) || - definition == typeof(IHandler<,>); - }); - - private IDictionary> GetSubscriptionKeys(object subscriber) - { - Dictionary> keys = []; - foreach (NotificationAttribute attribute in subscriber.GetAttributes()) - { - if (!keys.TryGetValue(attribute.Type, out List? value)) - { - value = ([]); - keys[attribute.Type] = value; - } - - if (subscriber.GetPropertyValue(() => attribute.Key) is object key) - { - value.Add(key); - } - else - { - value.Add(attribute.Key); - } - } - - return keys; - } - - private void RemoveSubscription(object subscriber, - string key) - { - if (subscriptions.TryGetValue(key, out List? subscribers)) - { - for (int i = subscribers.Count - 1; i >= 0; i--) - { - if (subscribers[i].Target == subscriber) - { - subscribers.RemoveAt(i); - } - } - - if (subscribers.Count == 0) - { - subscriptions.TryRemove(key, out _); - } - } - } - - private void RemoveSubscriptions(object subscriber, - IDictionary> subscribers, - Type handlerType) - { - if (subscribers.TryGetValue(handlerType, out List? keys)) - { - foreach (object key in keys) - { - string subscriptionKey = $"{(key is not null ? $"{key}:" : "")}{handlerType}"; - RemoveSubscription(subscriber, subscriptionKey); - } - } - else - { - string subscriptionKey = $"{handlerType}"; - RemoveSubscription(subscriber, subscriptionKey); - } - } -} \ No newline at end of file diff --git a/Toolkit.Foundation/SubscriptionCollection.cs b/Toolkit.Foundation/SubscriptionCollection.cs deleted file mode 100644 index 82f4572..0000000 --- a/Toolkit.Foundation/SubscriptionCollection.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.Collections.Concurrent; - -namespace Toolkit.Foundation; - -public class SubscriptionCollection : - ConcurrentDictionary>; \ No newline at end of file diff --git a/Toolkit.Foundation/WriteClipboardHandler.cs b/Toolkit.Foundation/WriteClipboardHandler.cs index ac58dfc..a86b170 100644 --- a/Toolkit.Foundation/WriteClipboardHandler.cs +++ b/Toolkit.Foundation/WriteClipboardHandler.cs @@ -1,9 +1,10 @@ namespace Toolkit.Foundation; public class WriteClipboardHandler(IClipboardWriter clipboardWriter) : - INotificationHandler>> + IAsyncHandler>> { - public async Task Handle(WriteEventArgs> args) + public async Task Handle(WriteEventArgs> args, + CancellationToken cancellationToken = default) { if (args.Sender is Clipboard clipboard) { diff --git a/Toolkit.Test/Program.cs b/Toolkit.Test/Program.cs new file mode 100644 index 0000000..41a06a3 --- /dev/null +++ b/Toolkit.Test/Program.cs @@ -0,0 +1,63 @@ +using CommunityToolkit.Mvvm.Messaging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Toolkit.Foundation; + +namespace Toolkit.Test +{ + public record User; + + public record Hello; + public class LoggedInUserHandler3 : IHandler + { + public LoggedInUserHandler3() + { + + } + public User Handle(Hello? args) + { + return new User(); + } + } + + public class LoggedInUserHandler4 : IHandler + { + public LoggedInUserHandler4() + { + + } + public void Handle(Hello? args) + { + } + } + + internal class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello, World!"); + + var test = DefaultHostBuilder.Create() + .ConfigureServices((context, services) => + { + services.AddHandler(); + services.AddHandler("Foo"); + + services.AddHostedService(); + }); + + + var d = test.Build(); + + d.Start(); + + var dd = d.Services.GetRequiredService(); + + // var sdd = d.Services.GetRequiredService(); + + // dd.Send(); + dd.Send("Foo"); + + } + } +} diff --git a/Toolkit.Test/Toolkit.Test.csproj b/Toolkit.Test/Toolkit.Test.csproj new file mode 100644 index 0000000..9e5637a --- /dev/null +++ b/Toolkit.Test/Toolkit.Test.csproj @@ -0,0 +1,18 @@ + + + + Exe + net9.0 + enable + enable + + + + + + + + + + + diff --git a/Toolkit.UI.Avalonia/NavigateAction.cs b/Toolkit.UI.Avalonia/NavigateAction.cs index cd9f277..3b46966 100644 --- a/Toolkit.UI.Avalonia/NavigateAction.cs +++ b/Toolkit.UI.Avalonia/NavigateAction.cs @@ -2,6 +2,7 @@ using Avalonia.Controls; using Avalonia.Metadata; using Avalonia.Xaml.Interactivity; +using CommunityToolkit.Mvvm.Messaging; using System.Collections.Immutable; using Toolkit.Foundation; @@ -63,7 +64,7 @@ public class NavigateAction : ImmutableDictionary? parameters = Parameters is { Count: > 0 } ? Parameters.ToImmutableDictionary(x => x.Key, x => x.Value) : ImmutableDictionary.Empty; - observableViewModel.Publisher.Publish(new NavigateEventArgs(Route, Region == this ? content : Region, Scope ?? null, + observableViewModel.Messenger.Send(new NavigateEventArgs(Route, Region == this ? content : Region, Scope ?? null, content.DataContext, Navigated, parameters)); } } diff --git a/Toolkit.UI.Avalonia/NavigateBackAction.cs b/Toolkit.UI.Avalonia/NavigateBackAction.cs index 62e6dbd..7fb5974 100644 --- a/Toolkit.UI.Avalonia/NavigateBackAction.cs +++ b/Toolkit.UI.Avalonia/NavigateBackAction.cs @@ -1,6 +1,7 @@ using Avalonia; using Avalonia.Controls.Primitives; using Avalonia.Xaml.Interactivity; +using CommunityToolkit.Mvvm.Messaging; using Toolkit.Foundation; namespace Toolkit.UI.Avalonia; @@ -34,7 +35,7 @@ public class NavigateBackAction : { if (control.DataContext is IObservableViewModel observableViewModel) { - observableViewModel.Publisher.Publish(new NavigateBackEventArgs(Region + observableViewModel.Messenger.Send(new NavigateBackEventArgs(Region ?? null, Scope ?? null)); } } diff --git a/Toolkit.Windows/PointerMonitor.cs b/Toolkit.Windows/PointerMonitor.cs index bc3e405..c3cf662 100644 --- a/Toolkit.Windows/PointerMonitor.cs +++ b/Toolkit.Windows/PointerMonitor.cs @@ -1,13 +1,13 @@ -using System.Diagnostics.CodeAnalysis; +using CommunityToolkit.Mvvm.Messaging; +using System.Diagnostics.CodeAnalysis; using System.Drawing; -using Toolkit.Foundation; using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.UI.WindowsAndMessaging; namespace Toolkit.Windows; -public class PointerMonitor(IPublisher publisher) : +public class PointerMonitor(IMessenger messenger) : IPointerMonitor { private bool isDisposed; @@ -99,16 +99,16 @@ public class PointerMonitor(IPublisher publisher) : isPointerDrag = true; } - publisher.Publish(new PointerDragEventArgs(location)); + messenger.Send(new PointerDragEventArgs(location)); } - publisher.Publish(new PointerMovedEventArgs(location)); + messenger.Send(new PointerMovedEventArgs(location)); } private void SendPointerPressed(PointerLocation location, PointerButton button) { isPointerPressed = true; - publisher.Publish(new PointerPressedEventArgs(location, button)); + messenger.Send(new PointerPressedEventArgs(location, button)); } private void SendPointerReleased(PointerLocation location, PointerButton button) @@ -118,11 +118,11 @@ public class PointerMonitor(IPublisher publisher) : if (isPointerDrag) { isPointerDrag = false; - publisher.Publish(new PointerDragReleasedEventArgs(location, button)); + messenger.Send(new PointerDragReleasedEventArgs(location, button)); } isPointerPressed = false; - publisher.Publish(new PointerReleasedEventArgs(location, button)); + messenger.Send(new PointerReleasedEventArgs(location, button)); } } diff --git a/Toolkit.Windows/Taskbar.cs b/Toolkit.Windows/Taskbar.cs index 64d6740..19c04db 100644 --- a/Toolkit.Windows/Taskbar.cs +++ b/Toolkit.Windows/Taskbar.cs @@ -1,23 +1,25 @@ -using Toolkit.Foundation; +using CommunityToolkit.Mvvm.Messaging; +using Toolkit.Foundation; using Windows.Win32; namespace Toolkit.Windows; -public class Taskbar(ISubscriber subscriber, - IPublisher publisher, +public class Taskbar(IMessenger messenger, IDisposer disposer) : ITaskbar, - INotificationHandler, - INotificationHandler, - INotificationHandler, - INotificationHandler + IRecipient, + IRecipient, + IRecipient, + IRecipient { private bool isDrag; private bool isWithinBounds; public void Dispose() { + messenger.UnregisterAll(this); disposer.Dispose(this); + GC.SuppressFinalize(this); } @@ -40,29 +42,25 @@ public class Taskbar(ISubscriber subscriber, public IntPtr GetHandle() => WindowHelper.Find("Shell_TrayWnd"); - public Task Handle(WndProcEventArgs args) + public void Receive(WndProcEventArgs args) { if (args.Message == PInvoke.WM_TASKBARCREATED || args.Message == (int)WndProcMessages.WM_SETTINGCHANGE && (int)args.WParam == PInvoke.SPI_SETWORKAREA) { - publisher.Publish(); + messenger.Send(); } - - return Task.CompletedTask; } - public Task Handle(PointerReleasedEventArgs args) + public void Receive(PointerReleasedEventArgs args) { if (isDrag) { isDrag = false; } - - return Task.CompletedTask; } - public Task Handle(PointerMovedEventArgs args) + public void Receive(PointerMovedEventArgs args) { nint taskbarHandle = GetHandle(); if (WindowHelper.TryGetBounds(taskbarHandle, out Rect? rect)) @@ -71,11 +69,11 @@ public class Taskbar(ISubscriber subscriber, { if (isWithinBounds) { - return Task.CompletedTask; + return; } isWithinBounds = true; - publisher.Publish(); + messenger.Send(); } else { @@ -83,21 +81,19 @@ public class Taskbar(ISubscriber subscriber, isWithinBounds = false; } } - - return Task.CompletedTask; } - public Task Handle(PointerDragEventArgs args) + public void Receive(PointerDragEventArgs args) { if (isWithinBounds) { if (isDrag) { - publisher.Publish(); + messenger.Send(); } else { - publisher.Publish(); + messenger.Send(); } isDrag = true; @@ -106,9 +102,7 @@ public class Taskbar(ISubscriber subscriber, { isDrag = false; } - - return Task.CompletedTask; } - public void Initialize() => subscriber.Subscribe(this); + public void Initialize() => messenger.RegisterAll(this); } diff --git a/Toolkit.Windows/TaskbarButton.cs b/Toolkit.Windows/TaskbarButton.cs index 80192e8..416fd81 100644 --- a/Toolkit.Windows/TaskbarButton.cs +++ b/Toolkit.Windows/TaskbarButton.cs @@ -1,31 +1,31 @@ -using Toolkit.Foundation; +using CommunityToolkit.Mvvm.Messaging; +using Toolkit.Foundation; namespace Toolkit.Windows; public class TaskbarButton : ITaskbarButton, - INotificationHandler, - INotificationHandler, - INotificationHandler + IRecipient, + IRecipient, + IRecipient { - private readonly IPublisher publisher; + private readonly IMessenger messenger; private readonly IDisposer disposer; private bool isWithinBounds; private bool isDrag; public TaskbarButton(string name, Rect rect, - IPublisher publisher, - ISubscriber subscriber, + IMessenger messenger, IDisposer disposer) { - this.publisher = publisher; + this.messenger = messenger; this.disposer = disposer; Name = name; Rect = rect; - subscriber.Subscribe(this); + messenger.RegisterAll(this); } public Rect Rect { get; internal set; } @@ -34,36 +34,36 @@ public class TaskbarButton : public void Dispose() { + messenger.UnregisterAll(this); disposer.Dispose(this); + GC.SuppressFinalize(this); } - public Task Handle(PointerReleasedEventArgs args) + public void Receive(PointerReleasedEventArgs args) { if (!isDrag && isWithinBounds) { - publisher.Publish(new TaskbarButtonInvokedEventArgs(this)); + messenger.Send(new TaskbarButtonInvokedEventArgs(this)); } if (isDrag) { isDrag = false; } - - return Task.CompletedTask; } - public Task Handle(PointerDragEventArgs args) + public void Receive(PointerDragEventArgs args) { if (isWithinBounds) { if (isDrag) { - publisher.Publish(new TaskbarButtonDragOverEventArgs(this)); + messenger.Send(new TaskbarButtonDragOverEventArgs(this)); } else { - publisher.Publish(new TaskbarButtonDragEnterEventArgs(this)); + messenger.Send(new TaskbarButtonDragEnterEventArgs(this)); } isDrag = true; @@ -72,28 +72,24 @@ public class TaskbarButton : { isDrag = false; } - - return Task.CompletedTask; } - public Task Handle(PointerMovedEventArgs args) + public void Receive(PointerMovedEventArgs args) { if (args.Location.IsWithinBounds(Rect)) { if (isWithinBounds) { - return Task.CompletedTask; + return; } isWithinBounds = true; - publisher.Publish(new TaskbarButtonEnteredEventArgs(this)); + messenger.Send(new TaskbarButtonEnteredEventArgs(this)); } else { isDrag = false; isWithinBounds = false; } - - return Task.CompletedTask; } } diff --git a/Toolkit.Windows/TaskbarButtonMonitor.cs b/Toolkit.Windows/TaskbarButtonMonitor.cs index 7f3ab69..abb1dbc 100644 --- a/Toolkit.Windows/TaskbarButtonMonitor.cs +++ b/Toolkit.Windows/TaskbarButtonMonitor.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using CommunityToolkit.Mvvm.Messaging; using Toolkit.Foundation; using UIAutomationClient; @@ -10,7 +10,7 @@ public class TaskbarButtonMonitor : private readonly IDispatcherTimer dispatcherTimer; private readonly IDispatcherTimerFactory dispatcherTimerFactory; private readonly IDisposer disposer; - private readonly IPublisher publisher; + private readonly IMessenger messenger; private readonly IServiceFactory serviceFactory; private readonly Dictionary taskbarButtons = []; private readonly ITaskbarList taskbarList; @@ -20,13 +20,13 @@ public class TaskbarButtonMonitor : private IntPtr taskListHandle; public TaskbarButtonMonitor(ITaskbarList taskbarList, - IPublisher publisher, + IMessenger messenger, IDispatcherTimerFactory dispatcherTimerFactory, IServiceFactory serviceFactory, IDisposer disposer) { this.taskbarList = taskbarList; - this.publisher = publisher; + this.messenger = messenger; this.dispatcherTimerFactory = dispatcherTimerFactory; this.serviceFactory = serviceFactory; this.disposer = disposer; @@ -121,10 +121,8 @@ public class TaskbarButtonMonitor : string key = buttonToRemove.Key; TaskbarButton button = buttonToRemove.Value; - Debug.WriteLine($"{key} button removed"); - taskbarButtons.Remove(key); - publisher.Publish(new TaskbarButtonRemovedEventArgs(button)); + messenger.Send(new TaskbarButtonRemovedEventArgs(button)); button.Dispose(); } @@ -141,17 +139,13 @@ public class TaskbarButtonMonitor : if (taskbarButtons.TryGetValue(name, out TaskbarButton? taskbarButton)) { - Debug.WriteLine($"{name} button updated"); - taskbarButtons[name].Rect = rect; - publisher.Publish(new TaskbarButtonUpdatedEventArgs(taskbarButtons[name])); + messenger.Send(new TaskbarButtonUpdatedEventArgs(taskbarButtons[name])); } else { - Debug.WriteLine($"{name} button added"); - taskbarButtons.Add(name, serviceFactory.Create(name, rect)); - publisher.Publish(new TaskbarButtonCreatedEventArgs(taskbarButtons[name])); + messenger.Send(new TaskbarButtonCreatedEventArgs(taskbarButtons[name])); } } } diff --git a/Toolkit.Windows/WndProcMonitor.cs b/Toolkit.Windows/WndProcMonitor.cs index 8fd5780..153ca7e 100644 --- a/Toolkit.Windows/WndProcMonitor.cs +++ b/Toolkit.Windows/WndProcMonitor.cs @@ -1,4 +1,4 @@ -using Toolkit.Foundation; +using CommunityToolkit.Mvvm.Messaging; using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.Graphics.Gdi; @@ -6,16 +6,16 @@ using Windows.Win32.UI.WindowsAndMessaging; namespace Toolkit.Windows; -public class WndProcMonitor(IPublisher publisher) : +public class WndProcMonitor(IMessenger messenger) : IWndProcMonitor { private WNDPROC? handler; - private readonly IPublisher publisher = publisher; public IntPtr Handle { get; private set; } public void Dispose() { + GC.SuppressFinalize(this); PInvoke.DestroyWindow((HWND)Handle); } @@ -54,7 +54,7 @@ public class WndProcMonitor(IPublisher publisher) : private LRESULT Wndproc(HWND param0, uint param1, WPARAM param2, LPARAM param3) { - publisher.Publish(new WndProcEventArgs(param1, (uint)param2.Value, (uint)param3.Value)); + messenger.Send(new WndProcEventArgs(param1, (uint)param2.Value, (uint)param3.Value)); return PInvoke.DefWindowProc(param0, param1, param2, param3); } diff --git a/Toolkit.sln b/Toolkit.sln index 8126778..b0b0258 100644 --- a/Toolkit.sln +++ b/Toolkit.sln @@ -15,6 +15,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Toolkit.Windows", "Toolkit. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Toolkit.WinUI", "Toolkit.WinUI\Toolkit.WinUI.csproj", "{D90BFF29-B38C-432E-849A-28C5A88A6DDD}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Toolkit.Test", "Toolkit.Test\Toolkit.Test.csproj", "{E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -97,6 +99,18 @@ Global {D90BFF29-B38C-432E-849A-28C5A88A6DDD}.Release|x64.Build.0 = Release|Any CPU {D90BFF29-B38C-432E-849A-28C5A88A6DDD}.Release|x86.ActiveCfg = Release|Any CPU {D90BFF29-B38C-432E-849A-28C5A88A6DDD}.Release|x86.Build.0 = Release|Any CPU + {E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}.Debug|x64.ActiveCfg = Debug|Any CPU + {E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}.Debug|x64.Build.0 = Debug|Any CPU + {E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}.Debug|x86.ActiveCfg = Debug|Any CPU + {E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}.Debug|x86.Build.0 = Debug|Any CPU + {E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}.Release|Any CPU.Build.0 = Release|Any CPU + {E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}.Release|x64.ActiveCfg = Release|Any CPU + {E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}.Release|x64.Build.0 = Release|Any CPU + {E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}.Release|x86.ActiveCfg = Release|Any CPU + {E125F8EF-6B66-400F-9CDE-BC3DB1463F4E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE