diff --git a/Toolkit.Avalonia/ContentDialogHandler.cs b/Toolkit.Avalonia/ContentDialogHandler.cs index f720d25..7a8cbfc 100644 --- a/Toolkit.Avalonia/ContentDialogHandler.cs +++ b/Toolkit.Avalonia/ContentDialogHandler.cs @@ -19,7 +19,7 @@ public class ContentDialogHandler : dialog.PrimaryButtonClick -= HandlePrimaryButtonClick; if (dialog.DataContext is object content) { - if (content is IPrimaryConfirmation primaryConfirmation) + if (content is IAsyncPrimaryConfirmation primaryConfirmation) { Deferral deferral = args.GetDeferral(); if (!await primaryConfirmation.ConfirmPrimary()) @@ -39,7 +39,7 @@ public class ContentDialogHandler : dialog.SecondaryButtonClick -= HandleSecondaryButtonClick; if (dialog.DataContext is object content) { - if (content is ISecondaryConfirmation secondaryConfirmation) + if (content is IAsyncSecondaryConfirmation secondaryConfirmation) { Deferral deferral = args.GetDeferral(); if (!await secondaryConfirmation.ConfirmSecondary()) @@ -63,7 +63,7 @@ public class ContentDialogHandler : if (dialog.DataContext is object content) { bool cancelled = false; - if (content is IConfirmation confirmation) + if (content is IAsyncConfirmation confirmation) { Deferral deferral = args.GetDeferral(); if (!await confirmation.Confirm()) diff --git a/Toolkit.Avalonia/FrameHandler.cs b/Toolkit.Avalonia/FrameHandler.cs index 96958cd..702e3df 100644 --- a/Toolkit.Avalonia/FrameHandler.cs +++ b/Toolkit.Avalonia/FrameHandler.cs @@ -60,7 +60,7 @@ public class FrameHandler(ITransientNavigationStore navigationStore) : if (sender.DataContext is object content) { - if (content is IConfirmation confirmation && + if (content is IAsyncConfirmation confirmation && !await confirmation.Confirm()) { args.Cancel = true; diff --git a/Toolkit.Avalonia/TaskDialogHandler.cs b/Toolkit.Avalonia/TaskDialogHandler.cs index 660393a..b7cf53e 100644 --- a/Toolkit.Avalonia/TaskDialogHandler.cs +++ b/Toolkit.Avalonia/TaskDialogHandler.cs @@ -26,7 +26,7 @@ public class TaskDialogHandler(ITopLevelProvider topLevelProvider) : if (args.Result is TaskDialogResult result) { if (result is TaskDialogResult.OK && content is - IPrimaryConfirmation primaryConfirmation) + IAsyncPrimaryConfirmation primaryConfirmation) { Deferral deferral = args.GetDeferral(); if (!await primaryConfirmation.ConfirmPrimary()) diff --git a/Toolkit.Foundation/AsyncHandlerInitialization.cs b/Toolkit.Foundation/AsyncHandlerInitialization.cs index 45da2be..0163a19 100644 --- a/Toolkit.Foundation/AsyncHandlerInitialization.cs +++ b/Toolkit.Foundation/AsyncHandlerInitialization.cs @@ -7,15 +7,38 @@ public class AsyncHandlerInitialization(IServiceP IInitialization where THandler : class, IAsyncHandler where TMessage : class { - public void Initialize() => StrongReferenceMessenger.Default.Register>(provider, - (provider, args) => args.Reply(provider.GetRequiredService().Handle(args.Message, args.CancellationToken))); - args.Reply(handler.Handle(args.Message, args.CancellationToken); + public void Initialize() + { + if (!StrongReferenceMessenger.Default.IsRegistered>(provider)) + { + StrongReferenceMessenger.Default.Register>(provider, + (provider, args) => + { + foreach (IAsyncHandler handler in provider.GetServices>()) + { + args.Reply(handler.Handle(args.Message, args.CancellationToken)); + } + }); + } + } } public class AsyncHandlerInitialization(IServiceProvider provider) : IInitialization where THandler : class, IAsyncHandler where TMessage : class { - public void Initialize() => StrongReferenceMessenger.Default.Register>(provider, - (provider, args) => provider.GetRequiredService().Handle(args.Message, args.CancellationToken)); -} \ No newline at end of file + public void Initialize() + { + if (!StrongReferenceMessenger.Default.IsRegistered(provider)) + { + StrongReferenceMessenger.Default.Register>(provider, + (provider, args) => + { + foreach (IAsyncHandler handler in provider.GetServices>()) + { + handler.Handle(args.Message, args.CancellationToken); + } + }); + } + } +} diff --git a/Toolkit.Foundation/AsyncHandlerKeyedInitialization.cs b/Toolkit.Foundation/AsyncHandlerKeyedInitialization.cs new file mode 100644 index 0000000..0233722 --- /dev/null +++ b/Toolkit.Foundation/AsyncHandlerKeyedInitialization.cs @@ -0,0 +1,44 @@ +using CommunityToolkit.Mvvm.Messaging; +using Microsoft.Extensions.DependencyInjection; + +namespace Toolkit.Foundation; + +public class AsyncHandlerKeyedInitialization(string key, IServiceProvider provider) : + IInitialization where THandler : class, IAsyncHandler + where TMessage : class +{ + public void Initialize() + { + if (!StrongReferenceMessenger.Default.IsRegistered(provider, key)) + { + StrongReferenceMessenger.Default.Register(provider, key, + (provider, args) => + { + foreach (IAsyncHandler handler in provider.GetKeyedServices>(key)) + { + handler.Handle(args); + } + }); + } + } +} + +public class AsyncHandlerKeyedInitialization(string key, IServiceProvider provider) : + IInitialization where THandler : class, IAsyncHandler + where TMessage : class +{ + public void Initialize() + { + if (!StrongReferenceMessenger.Default.IsRegistered, string>(provider, key)) + { + StrongReferenceMessenger.Default.Register, string>(provider, key, + (provider, args) => + { + foreach (IAsyncHandler handler in provider.GetKeyedServices>(key)) + { + handler.Handle(args.Message); + } + }); + } + } +} \ No newline at end of file diff --git a/Toolkit.Foundation/Create.cs b/Toolkit.Foundation/Create.cs index 0973a5d..805c72e 100644 --- a/Toolkit.Foundation/Create.cs +++ b/Toolkit.Foundation/Create.cs @@ -2,9 +2,9 @@ public record Create { - public static CreateEventArgs As(TSender sender, params object[] parameters) => - new(sender, parameters); + public static CreateEventArgs As(TSender sender) => + new(sender); public static CreateEventArgs As(params object[] parameters) where TSender : new() => - new(new TSender(), parameters); + new(new TSender()); } \ No newline at end of file diff --git a/Toolkit.Foundation/CreateEventArgs.cs b/Toolkit.Foundation/CreateEventArgs.cs index 4778dc5..3550caf 100644 --- a/Toolkit.Foundation/CreateEventArgs.cs +++ b/Toolkit.Foundation/CreateEventArgs.cs @@ -1,4 +1,3 @@ namespace Toolkit.Foundation; -public record CreateEventArgs(TSender? Sender = default, - params object[] Parameters); \ No newline at end of file +public record CreateEventArgs(TSender? Sender = default); \ No newline at end of file diff --git a/Toolkit.Foundation/HandlerInitialization.cs b/Toolkit.Foundation/HandlerInitialization.cs index 3648eec..639e9b3 100644 --- a/Toolkit.Foundation/HandlerInitialization.cs +++ b/Toolkit.Foundation/HandlerInitialization.cs @@ -7,22 +7,38 @@ public class HandlerInitialization(IServiceProvid IInitialization where THandler : class, IHandler where TMessage : class { - public void Initialize() => StrongReferenceMessenger.Default.Register>(provider, - (provider, args) => args.Reply(provider.GetRequiredService().Handle(args.Message))); + public void Initialize() + { + if (!StrongReferenceMessenger.Default.IsRegistered>(provider)) + { + StrongReferenceMessenger.Default.Register>(provider, + (provider, args) => + { + foreach (IHandler handler in provider.GetServices>()) + { + handler.Handle(args.Message); + } + }); + } + } } public class HandlerInitialization(IServiceProvider provider) : IInitialization where THandler : class, IHandler where TMessage : class { - public void Initialize() => StrongReferenceMessenger.Default.Register(provider, - (provider, args) => provider.GetRequiredService().Handle(args)); + public void Initialize() + { + if (!StrongReferenceMessenger.Default.IsRegistered(provider)) + { + StrongReferenceMessenger.Default.Register(provider, + (provider, args) => + { + foreach (IHandler handler in provider.GetServices>()) + { + handler.Handle(args); + } + }); + } + } } - -public class HandlerKeyedInitialization(string key, IServiceProvider provider) : - IInitialization where THandler : class, IHandler - where TMessage : class -{ - public void Initialize() => StrongReferenceMessenger.Default.Register(provider, key, - (provider, args) => provider.GetRequiredKeyedService(key).Handle(args)); -} \ No newline at end of file diff --git a/Toolkit.Foundation/HandlerKeyedInitialization.cs b/Toolkit.Foundation/HandlerKeyedInitialization.cs new file mode 100644 index 0000000..fd82f27 --- /dev/null +++ b/Toolkit.Foundation/HandlerKeyedInitialization.cs @@ -0,0 +1,44 @@ +using CommunityToolkit.Mvvm.Messaging; +using Microsoft.Extensions.DependencyInjection; + +namespace Toolkit.Foundation; + +public class HandlerKeyedInitialization(string key, IServiceProvider provider) : + IInitialization where THandler : class, IHandler + where TMessage : class +{ + public void Initialize() + { + if (!StrongReferenceMessenger.Default.IsRegistered(provider, key)) + { + StrongReferenceMessenger.Default.Register(provider, key, + (provider, args) => + { + foreach (IHandler handler in provider.GetKeyedServices>(key)) + { + handler.Handle(args); + } + }); + } + } +} + +public class HandlerKeyedInitialization(string key, IServiceProvider provider) : + IInitialization where THandler : class, IHandler + where TMessage : class +{ + public void Initialize() + { + if (!StrongReferenceMessenger.Default.IsRegistered, string>(provider, key)) + { + StrongReferenceMessenger.Default.Register, string>(provider, key, + (provider, args) => + { + foreach (IHandler handler in provider.GetKeyedServices>(key)) + { + handler.Handle(args.Message); + } + }); + } + } +} \ No newline at end of file diff --git a/Toolkit.Foundation/IConfirmation.cs b/Toolkit.Foundation/IAsyncConfirmation.cs similarity index 63% rename from Toolkit.Foundation/IConfirmation.cs rename to Toolkit.Foundation/IAsyncConfirmation.cs index 60a227d..d309381 100644 --- a/Toolkit.Foundation/IConfirmation.cs +++ b/Toolkit.Foundation/IAsyncConfirmation.cs @@ -1,6 +1,6 @@ namespace Toolkit.Foundation; -public interface IConfirmation +public interface IAsyncConfirmation { Task Confirm(); } \ No newline at end of file diff --git a/Toolkit.Foundation/IPrimaryConfirmation.cs b/Toolkit.Foundation/IAsyncPrimaryConfirmation.cs similarity index 61% rename from Toolkit.Foundation/IPrimaryConfirmation.cs rename to Toolkit.Foundation/IAsyncPrimaryConfirmation.cs index 1e5726a..9176c2b 100644 --- a/Toolkit.Foundation/IPrimaryConfirmation.cs +++ b/Toolkit.Foundation/IAsyncPrimaryConfirmation.cs @@ -1,6 +1,6 @@ namespace Toolkit.Foundation; -public interface IPrimaryConfirmation +public interface IAsyncPrimaryConfirmation { Task ConfirmPrimary(); } \ No newline at end of file diff --git a/Toolkit.Foundation/ISecondaryConfirmation.cs b/Toolkit.Foundation/IAsyncSecondaryConfirmation.cs similarity index 61% rename from Toolkit.Foundation/ISecondaryConfirmation.cs rename to Toolkit.Foundation/IAsyncSecondaryConfirmation.cs index dd4d66b..64899d8 100644 --- a/Toolkit.Foundation/ISecondaryConfirmation.cs +++ b/Toolkit.Foundation/IAsyncSecondaryConfirmation.cs @@ -1,6 +1,6 @@ namespace Toolkit.Foundation; -public interface ISecondaryConfirmation +public interface IAsyncSecondaryConfirmation { Task ConfirmSecondary(); } \ No newline at end of file diff --git a/Toolkit.Foundation/IIndexed.cs b/Toolkit.Foundation/IIndexed.cs deleted file mode 100644 index c25bb5c..0000000 --- a/Toolkit.Foundation/IIndexed.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Toolkit.Foundation; - -public interface IIndexed -{ - public int Index { get; } -} \ No newline at end of file diff --git a/Toolkit.Foundation/IServiceCollectionExtensions.cs b/Toolkit.Foundation/IServiceCollectionExtensions.cs index 85bc99d..6fc9487 100644 --- a/Toolkit.Foundation/IServiceCollectionExtensions.cs +++ b/Toolkit.Foundation/IServiceCollectionExtensions.cs @@ -5,23 +5,51 @@ namespace Toolkit.Foundation; public static class IServiceCollectionExtensions { public static IServiceCollection AddAsyncHandler(this IServiceCollection services, - ServiceLifetime lifetime = ServiceLifetime.Transient) + string key) + where THandler : class, IAsyncHandler + where TMessage : class => AddAsyncHandler(services, ServiceLifetime.Transient, key); + + public static IServiceCollection AddAsyncHandler(this IServiceCollection services, + ServiceLifetime lifetime = ServiceLifetime.Transient, + string? key = null) where THandler : class, IAsyncHandler where TMessage : class { - services.Add(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime)); - services.AddInitialization>(); + if (key is { Length: > 0 }) + { + services.Add(new ServiceDescriptor(typeof(IAsyncHandler), key, typeof(THandler), lifetime)); + services.AddInitialization>>(key); + } + else + { + services.Add(new ServiceDescriptor(typeof(IAsyncHandler), typeof(THandler), lifetime)); + services.AddInitialization>>(); + } return services; } public static IServiceCollection AddAsyncHandler(this IServiceCollection services, - ServiceLifetime lifetime = ServiceLifetime.Transient) + string key) + where THandler : class, IAsyncHandler + where TMessage : class => AddAsyncHandler(services, ServiceLifetime.Transient, key); + + public static IServiceCollection AddAsyncHandler(this IServiceCollection services, + ServiceLifetime lifetime = ServiceLifetime.Transient, + string? key = null) where THandler : class, IAsyncHandler where TMessage : class { - services.Add(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime)); - services.AddInitialization>(); + if (key is { Length: > 0 }) + { + services.Add(new ServiceDescriptor(typeof(IAsyncHandler), key, typeof(THandler), lifetime)); + services.AddInitialization>>(key); + } + else + { + services.Add(new ServiceDescriptor(typeof(IAsyncHandler), typeof(THandler), lifetime)); + services.AddInitialization>>(); + } return services; } @@ -35,7 +63,7 @@ public static class IServiceCollectionExtensions } public static IServiceCollection AddCache(this IServiceCollection services) - where TKey : notnull + where TKey : notnull where TValue : notnull { services.AddScoped, Cache>(); @@ -61,12 +89,26 @@ public static class IServiceCollectionExtensions } public static IServiceCollection AddHandler(this IServiceCollection services, - ServiceLifetime lifetime = ServiceLifetime.Transient) + 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 : class, IHandler where TMessage : class { - services.Add(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime)); - services.AddInitialization>(); + if (key is { Length: > 0 }) + { + services.Add(new ServiceDescriptor(typeof(IHandler), key, typeof(THandler), lifetime)); + services.AddInitialization>>(key); + } + else + { + services.Add(new ServiceDescriptor(typeof(IHandler), typeof(THandler), lifetime)); + services.AddInitialization>>(); + } return services; } @@ -84,13 +126,13 @@ public static class IServiceCollectionExtensions { if (key is { Length: > 0}) { - services.Add(new ServiceDescriptor(typeof(THandler), key, typeof(THandler), lifetime)); - services.AddInitialization>(key); + services.Add(new ServiceDescriptor(typeof(IHandler), key, typeof(THandler), lifetime)); + services.AddInitialization>>(key); } else { - services.Add(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime)); - services.AddInitialization>(); + services.Add(new ServiceDescriptor(typeof(IHandler), typeof(THandler), lifetime)); + services.AddInitialization>>(); } return services; @@ -147,7 +189,7 @@ public static class IServiceCollectionExtensions public static IServiceCollection AddTemplate(this IServiceCollection services, object? key = null, ServiceLifetime serviceLifetime = ServiceLifetime.Transient, - params object[]? parameters) + params object?[]? parameters) { Type viewModelType = typeof(TViewModel); Type viewModelImplementationType = typeof(TViewModelImplementation); @@ -190,7 +232,7 @@ public static class IServiceCollectionExtensions Action writeDelegate, object? key = null, ServiceLifetime serviceLifetime = ServiceLifetime.Transient, - params object[]? parameters) + params object?[]? parameters) { parameters = [readDelegate, writeDelegate, .. parameters ?? Enumerable.Empty()]; return AddTemplate(services, key, serviceLifetime, parameters); @@ -201,7 +243,7 @@ public static class IServiceCollectionExtensions Action writeDelegate, object? key = null, ServiceLifetime serviceLifetime = ServiceLifetime.Transient, - params object[]? parameters) + params object?[]? parameters) { parameters = [readDelegate, writeDelegate, .. parameters ?? Enumerable.Empty()]; return AddTemplate(services, key, serviceLifetime, parameters); diff --git a/Toolkit.UI.WinUI/Toolkit.UI.WinUI.csproj b/Toolkit.UI.WinUI/Toolkit.UI.WinUI.csproj index ef332bb..f9d1c54 100644 --- a/Toolkit.UI.WinUI/Toolkit.UI.WinUI.csproj +++ b/Toolkit.UI.WinUI/Toolkit.UI.WinUI.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/Toolkit.WinUI/ContentDialogHandler.cs b/Toolkit.WinUI/ContentDialogHandler.cs index fe80451..91e252f 100644 --- a/Toolkit.WinUI/ContentDialogHandler.cs +++ b/Toolkit.WinUI/ContentDialogHandler.cs @@ -30,7 +30,7 @@ public class ContentDialogHandler : dialog.PrimaryButtonClick -= HandlePrimaryButtonClick; if (dialog.DataContext is object content) { - if (content is IPrimaryConfirmation primaryConfirmation) + if (content is IAsyncPrimaryConfirmation primaryConfirmation) { ContentDialogButtonClickDeferral deferral = args.GetDeferral(); if (!await primaryConfirmation.ConfirmPrimary()) @@ -50,7 +50,7 @@ public class ContentDialogHandler : dialog.SecondaryButtonClick -= HandleSecondaryButtonClick; if (dialog.DataContext is object content) { - if (content is ISecondaryConfirmation secondaryConfirmation) + if (content is IAsyncSecondaryConfirmation secondaryConfirmation) { ContentDialogButtonClickDeferral deferral = args.GetDeferral(); if (!await secondaryConfirmation.ConfirmSecondary()) @@ -73,7 +73,7 @@ public class ContentDialogHandler : dialog.Closing -= HandleClosing; if (dialog.DataContext is object content) { - if (content is IConfirmation confirmation) + if (content is IAsyncConfirmation confirmation) { ContentDialogClosingDeferral deferral = args.GetDeferral(); if (!await confirmation.Confirm()) diff --git a/Toolkit.WinUI/Toolkit.WinUI.csproj b/Toolkit.WinUI/Toolkit.WinUI.csproj index 4844a14..57e7954 100644 --- a/Toolkit.WinUI/Toolkit.WinUI.csproj +++ b/Toolkit.WinUI/Toolkit.WinUI.csproj @@ -18,7 +18,7 @@ - +