diff --git a/Toolkit.Avalonia/FrameHandler.cs b/Toolkit.Avalonia/FrameHandler.cs index 6d9a83a..3dbcdd8 100644 --- a/Toolkit.Avalonia/FrameHandler.cs +++ b/Toolkit.Avalonia/FrameHandler.cs @@ -147,23 +147,23 @@ public class FrameHandler : }; break; } + } - if (args.Parameters.TryGetValue("IsBackStackEnabled", out object? isBackStackEnabled)) + if (args.Parameters.TryGetValue("IsBackStackEnabled", out object? isBackStackEnabled)) + { + if (isBackStackEnabled is bool value) { - if (isBackStackEnabled is bool value) - { - navigationOptions.IsNavigationStackEnabled = value; - } + navigationOptions.IsNavigationStackEnabled = value; } + } - if (args.Parameters.TryGetValue("ClearBackStack", out object? clearBackStack)) + if (args.Parameters.TryGetValue("ClearBackStack", out object? clearBackStack)) + { + if (clearBackStack is bool value) { - if (clearBackStack is bool value) + if (value) { - if (value) - { - postNavigateActions.Add(() => CleanUp()); - } + postNavigateActions.Add(() => CleanUp()); } } } diff --git a/Toolkit.Foundation/ComponentBuilder.cs b/Toolkit.Foundation/ComponentBuilder.cs index ca508c4..08496d2 100644 --- a/Toolkit.Foundation/ComponentBuilder.cs +++ b/Toolkit.Foundation/ComponentBuilder.cs @@ -24,8 +24,7 @@ public class ComponentBuilder : services.AddScoped(); services.AddScoped(provider => - new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, - parameters?.Where(x => x is not null).ToArray()!))); + new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, parameters!))); services.AddSingleton(); diff --git a/Toolkit.Foundation/DefaultHostBuilder.cs b/Toolkit.Foundation/DefaultHostBuilder.cs index b58e9db..5e8026e 100644 --- a/Toolkit.Foundation/DefaultHostBuilder.cs +++ b/Toolkit.Foundation/DefaultHostBuilder.cs @@ -18,8 +18,7 @@ public class DefaultHostBuilder : .ConfigureServices((context, services) => { services.AddScoped(provider => - new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, - parameters?.Where(x => x is not null).ToArray()!))); + new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, parameters!))); services.AddSingleton(); diff --git a/Toolkit.Foundation/HandlerProvider.cs b/Toolkit.Foundation/HandlerProvider.cs index a8f7939..e0ce08f 100644 --- a/Toolkit.Foundation/HandlerProvider.cs +++ b/Toolkit.Foundation/HandlerProvider.cs @@ -3,12 +3,10 @@ public class HandlerProvider(SubscriptionCollection subscriptions) : IHandlerProvider { - public IEnumerable Get(Type type, - object? key = null) + public IEnumerable Get(object key) { var d = subscriptions; - string subscriptionKey = $"{(key is not null ? $"{key}:" : "")}{type}"; - if (subscriptions.TryGetValue(subscriptionKey, out List? subscribers)) + if (subscriptions.TryGetValue(key, out List? subscribers)) { foreach (WeakReference weakRef in subscribers.ToArray()) { diff --git a/Toolkit.Foundation/IHandlerProvider.cs b/Toolkit.Foundation/IHandlerProvider.cs index 94005b4..6ce7f05 100644 --- a/Toolkit.Foundation/IHandlerProvider.cs +++ b/Toolkit.Foundation/IHandlerProvider.cs @@ -2,6 +2,5 @@ public interface IHandlerProvider { - IEnumerable Get(Type type, - object? key = null); + IEnumerable Get(object key); } \ No newline at end of file diff --git a/Toolkit.Foundation/IServiceCollectionExtensions.cs b/Toolkit.Foundation/IServiceCollectionExtensions.cs index 2679438..44e11e1 100644 --- a/Toolkit.Foundation/IServiceCollectionExtensions.cs +++ b/Toolkit.Foundation/IServiceCollectionExtensions.cs @@ -49,38 +49,18 @@ public static class IServiceCollectionExtensions contract.GetGenericArguments() is { Length: 1 } notificationHandlerArguments) { Type notificationType = notificationHandlerArguments[0]; + Type wrapperType = typeof(NotificationHandlerWrapper<>).MakeGenericType(notificationType); - Type wrapperType = typeof(NotificationHandlerWrapper<>) - .MakeGenericType(notificationType); + string actualKey = $"{(key is not null ? $"{key}:" : "")}{notificationType}"; - if (key is not null) - { - services.Add(new ServiceDescriptor(typeof(INotificationHandler<>) - .MakeGenericType(notificationType), key, typeof(THandler), lifetime)); - } - else - { - services.Add(new ServiceDescriptor(typeof(INotificationHandler<>) - .MakeGenericType(notificationType), typeof(THandler), lifetime)); - } + services.Add(new ServiceDescriptor(typeof(INotificationHandler<>) + .MakeGenericType(notificationType), actualKey, typeof(THandler), lifetime)); - - if (key is not null) - { - services.Add(new ServiceDescriptor(wrapperType, key, (provider, key) => + services.Add(new ServiceDescriptor(wrapperType, actualKey, (provider, registeredKey) => provider.GetService()?.Create(wrapperType, - provider.GetRequiredKeyedService(typeof(INotificationHandler<>).MakeGenericType(notificationType), key), + provider.GetRequiredKeyedService(typeof(INotificationHandler<>).MakeGenericType(notificationType), registeredKey), provider.GetServices(typeof(IPipelineBehaviour<>) .MakeGenericType(notificationType)))!, lifetime)); - } - else - { - services.Add(new ServiceDescriptor(wrapperType, provider => - provider.GetService()?.Create(wrapperType, - provider.GetRequiredService(typeof(INotificationHandler<>).MakeGenericType(notificationType)), - provider.GetServices(typeof(IPipelineBehaviour<>) - .MakeGenericType(notificationType)))!, lifetime)); - } } if (contract.Name == typeof(IHandler<,>).Name && @@ -89,36 +69,17 @@ public static class IServiceCollectionExtensions Type requestType = handlerArguments[0]; Type responseType = handlerArguments[1]; - Type wrapperType = typeof(HandlerWrapper<,>) - .MakeGenericType(requestType, responseType); + Type wrapperType = typeof(HandlerWrapper<,>).MakeGenericType(requestType, responseType); + string actualKey = $"{(key is not null ? $"{key}:" : "")}{wrapperType}"; - if (key is not null) - { - services.Add(new ServiceDescriptor(typeof(THandler), key, - typeof(THandler), lifetime)); - } - else - { - services.Add(new ServiceDescriptor(typeof(THandler), - typeof(THandler), lifetime)); - } + services.Add(new ServiceDescriptor(typeof(THandler), actualKey, + typeof(THandler), lifetime)); - if (key is not null) - { - services.Add(new ServiceDescriptor(wrapperType, key, (provider, key) => - provider.GetService()?.Create(wrapperType, - provider.GetRequiredKeyedService(key), - provider.GetServices(typeof(IPipelineBehaviour<,>) - .MakeGenericType(requestType, responseType)))!, lifetime)); - } - else - { - services.Add(new ServiceDescriptor(wrapperType, provider => - provider.GetService()?.Create(wrapperType, - provider.GetRequiredService(), - provider.GetServices(typeof(IPipelineBehaviour<,>) - .MakeGenericType(requestType, responseType)))!, lifetime)); - } + services.Add(new ServiceDescriptor(wrapperType, actualKey, (provider, actualKey) => + provider.GetService()?.Create(wrapperType, + provider.GetRequiredKeyedService(actualKey), + provider.GetServices(typeof(IPipelineBehaviour<,>) + .MakeGenericType(requestType, responseType)))!, lifetime)); } } diff --git a/Toolkit.Foundation/Mediator.cs b/Toolkit.Foundation/Mediator.cs index 14e4b2c..9e2dda7 100644 --- a/Toolkit.Foundation/Mediator.cs +++ b/Toolkit.Foundation/Mediator.cs @@ -13,12 +13,15 @@ public class Mediator(IHandlerProvider handlerProvider, CancellationToken cancellationToken = default) where TMessage : notnull { - List handlers = GetHandlers(message, key); + 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 != null) + if (handleMethod is not null) { return await (Task)handleMethod.Invoke(handler, new object[] { message, cancellationToken })!; } @@ -33,14 +36,16 @@ public class Mediator(IHandlerProvider handlerProvider, CancellationToken cancellationToken = default) { Type messageType = message.GetType(); - Type handlerWrapperType = typeof(HandlerWrapper<,>).MakeGenericType(message.GetType(), responseType); - - List handlers = GetHandlers(message, handlerWrapperType, key); + 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 != null) + MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", + [messageType, typeof(CancellationToken)]); + + if (handleMethod is not null) { dynamic task = handleMethod.Invoke(handler, new object[] { message, cancellationToken })!; await task; @@ -86,44 +91,45 @@ public class Mediator(IHandlerProvider handlerProvider, [EnumeratorCancellation] CancellationToken cancellationToken = default) { Type messageType = message.GetType(); - Type handlerWrapperType = typeof(HandlerWrapper<,>).MakeGenericType(message.GetType(), responseType); + Type handlerType = typeof(HandlerWrapper<,>).MakeGenericType(message.GetType(), responseType); + key = $"{(key is not null ? $"{key}:" : "")}{handlerType}"; - List handlers = GetHandlers(message, handlerWrapperType, key); + List handlers = GetHandlers(message, handlerType, key); foreach (object? handler in handlers) { - MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", [messageType, typeof(CancellationToken)]); - if (handleMethod != null) + MethodInfo? handleMethod = handler?.GetType().GetMethod("Handle", + [messageType, typeof(CancellationToken)]); + + if (handleMethod is not null) { yield return await (Task)handleMethod.Invoke(handler, new object[] { message, cancellationToken })!; } } } + public async IAsyncEnumerable HandleManyAsync(TMessage message, object? key = null, [EnumeratorCancellation] CancellationToken cancellationToken = default) where TMessage : notnull { - List handlers = GetHandlers(message, key); + 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 != null) + if (handleMethod is not null) { yield return await (Task)handleMethod.Invoke(handler, new object[] { message, cancellationToken })!; } } } - private List GetHandlers(TMessage message, object? key) - where TMessage : notnull - { - Type messageType = message.GetType(); - Type handlerWrapperType = typeof(HandlerWrapper<,>).MakeGenericType(messageType, typeof(TResponse)); - - return GetHandlers(message, handlerWrapperType, key); - } - - private List GetHandlers(object message, Type handlerWrapperType, object? key) + private List GetHandlers(object message, + Type handlerWrapperType, + object? key) { Type messageType = message.GetType(); Dictionary> handlers = []; @@ -145,11 +151,11 @@ public class Mediator(IHandlerProvider handlerProvider, } } - IEnumerable keyedServices = key != null ? provider.GetKeyedServices(handlerWrapperType, key) : + IEnumerable keyedServices = key is not null ? provider.GetKeyedServices(handlerWrapperType, key) : provider.GetServices(handlerWrapperType); AddHandlers(keyedServices); - IEnumerable additionalHandlers = handlerProvider.Get(messageType, key); + IEnumerable additionalHandlers = handlerProvider.Get(key); AddHandlers(additionalHandlers); return handlers.SelectMany(entry => entry.Value).ToList(); diff --git a/Toolkit.Foundation/NavigateHandler.cs b/Toolkit.Foundation/NavigateHandler.cs index dd1be47..5b82db9 100644 --- a/Toolkit.Foundation/NavigateHandler.cs +++ b/Toolkit.Foundation/NavigateHandler.cs @@ -8,31 +8,31 @@ public class NavigateHandler(NamedComponent scope, { public Task Handle(NavigateEventArgs args) { - INavigation? navigationScope = null; + INavigation? navigation = null; if (args.Scope is "self" || args.Scope is "new") { if (args.Sender is IServiceProviderRequired requireServiceProvider) { if (args.Scope is "self") { - navigationScope = requireServiceProvider.Provider.GetRequiredService(); + navigation = requireServiceProvider.Provider.GetRequiredService(); } if (args.Scope is "new") { IServiceScope serviceScope = requireServiceProvider.Provider.CreateScope(); - navigationScope = serviceScope.ServiceProvider.GetRequiredService(); + navigation = serviceScope.ServiceProvider.GetRequiredService(); } } } - if (navigationScope is null) + if (navigation is null) { ComponentScopeDescriptor? descriptor = componentScopeProvider.Get(args.Scope ?? scope.Name); - navigationScope = descriptor?.Services?.GetRequiredService(); + navigation = descriptor?.Services?.GetRequiredService(); } - navigationScope?.Navigate(args.Route, args.Sender, + navigation?.Navigate(args.Route, args.Sender, args.Region, args.Navigated, args.Parameters); return Task.CompletedTask; diff --git a/Toolkit.Foundation/Publisher.cs b/Toolkit.Foundation/Publisher.cs index 41efe72..0020d12 100644 --- a/Toolkit.Foundation/Publisher.cs +++ b/Toolkit.Foundation/Publisher.cs @@ -30,10 +30,15 @@ public class Publisher(IHandlerProvider handlerProvider, Type handlerType = typeof(NotificationHandlerWrapper<>) .MakeGenericType(notificationType); - List handlers = key is not null ? serviceProvider.GetKeyedServices(handlerType, key).ToList() : - serviceProvider.GetServices(handlerType).ToList(); + key = $"{(key is not null ? $"{key}:" : "")}{notificationType}"; - foreach (object? handler in handlerProvider.Get(notificationType, key)) + List handlers = []; + foreach (object? handler in handlerProvider.Get(key)) + { + handlers.Add(handler); + } + + foreach (object? handler in serviceProvider.GetKeyedServices(handlerType, key)) { handlers.Add(handler); } diff --git a/Toolkit.UI.Avalonia/NavigateBackAction.cs b/Toolkit.UI.Avalonia/NavigateBackAction.cs index 62e6dbd..f31b73d 100644 --- a/Toolkit.UI.Avalonia/NavigateBackAction.cs +++ b/Toolkit.UI.Avalonia/NavigateBackAction.cs @@ -2,6 +2,7 @@ using Avalonia.Controls.Primitives; using Avalonia.Xaml.Interactivity; using Toolkit.Foundation; +using Toolkit.UI.Controls.Avalonia; namespace Toolkit.UI.Avalonia;