fixed a bunch of isses with keyed handlers

This commit is contained in:
TheXamlGuy
2024-06-22 13:03:14 +01:00
parent 8d76b712be
commit 34d3cc313b
10 changed files with 77 additions and 109 deletions
+1 -1
View File
@@ -147,6 +147,7 @@ public class FrameHandler :
};
break;
}
}
if (args.Parameters.TryGetValue("IsBackStackEnabled", out object? isBackStackEnabled))
{
@@ -167,7 +168,6 @@ public class FrameHandler :
}
}
}
}
frame.NavigateFromObject(control, navigationOptions);
foreach (Action postAction in postNavigateActions)
+1 -2
View File
@@ -24,8 +24,7 @@ public class ComponentBuilder :
services.AddScoped<IComponentHost, ComponentHost>();
services.AddScoped<IServiceFactory>(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<IDisposer, Disposer>();
+1 -2
View File
@@ -18,8 +18,7 @@ public class DefaultHostBuilder :
.ConfigureServices((context, services) =>
{
services.AddScoped<IServiceFactory>(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<IComponentHostCollection,
ComponentHostCollection>();
+2 -4
View File
@@ -3,12 +3,10 @@
public class HandlerProvider(SubscriptionCollection subscriptions) :
IHandlerProvider
{
public IEnumerable<object?> Get(Type type,
object? key = null)
public IEnumerable<object?> Get(object key)
{
var d = subscriptions;
string subscriptionKey = $"{(key is not null ? $"{key}:" : "")}{type}";
if (subscriptions.TryGetValue(subscriptionKey, out List<WeakReference>? subscribers))
if (subscriptions.TryGetValue(key, out List<WeakReference>? subscribers))
{
foreach (WeakReference weakRef in subscribers.ToArray())
{
+1 -2
View File
@@ -2,6 +2,5 @@
public interface IHandlerProvider
{
IEnumerable<object?> Get(Type type,
object? key = null);
IEnumerable<object?> Get(object key);
}
@@ -49,39 +49,19 @@ 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));
}
.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<IServiceFactory>()?.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<IServiceFactory>()?.Create(wrapperType,
provider.GetRequiredService(typeof(INotificationHandler<>).MakeGenericType(notificationType)),
provider.GetServices(typeof(IPipelineBehaviour<>)
.MakeGenericType(notificationType)))!, lifetime));
}
}
if (contract.Name == typeof(IHandler<,>).Name &&
contract.GetGenericArguments() is { Length: 2 } handlerArguments)
@@ -89,37 +69,18 @@ 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,
services.Add(new ServiceDescriptor(typeof(THandler), actualKey,
typeof(THandler), lifetime));
}
else
{
services.Add(new ServiceDescriptor(typeof(THandler),
typeof(THandler), lifetime));
}
if (key is not null)
{
services.Add(new ServiceDescriptor(wrapperType, key, (provider, key) =>
services.Add(new ServiceDescriptor(wrapperType, actualKey, (provider, actualKey) =>
provider.GetService<IServiceFactory>()?.Create(wrapperType,
provider.GetRequiredKeyedService<THandler>(key),
provider.GetRequiredKeyedService<THandler>(actualKey),
provider.GetServices(typeof(IPipelineBehaviour<,>)
.MakeGenericType(requestType, responseType)))!, lifetime));
}
else
{
services.Add(new ServiceDescriptor(wrapperType, provider =>
provider.GetService<IServiceFactory>()?.Create(wrapperType,
provider.GetRequiredService<THandler>(),
provider.GetServices(typeof(IPipelineBehaviour<,>)
.MakeGenericType(requestType, responseType)))!, lifetime));
}
}
}
return services;
+31 -25
View File
@@ -13,12 +13,15 @@ public class Mediator(IHandlerProvider handlerProvider,
CancellationToken cancellationToken = default)
where TMessage : notnull
{
List<object?> handlers = GetHandlers<TMessage, TResponse>(message, key);
Type messageType = message.GetType();
Type handlerType = typeof(HandlerWrapper<,>).MakeGenericType(messageType, typeof(TResponse));
key = $"{(key is not null ? $"{key}:" : "")}{handlerType}";
List<object?> 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<TResponse?>)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<object?> handlers = GetHandlers(message, handlerWrapperType, key);
Type handlerType = typeof(HandlerWrapper<,>).MakeGenericType(message.GetType(), responseType);
key = $"{(key is not null ? $"{key}:" : "")}{handlerType}";
List<object?> 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<object?> handlers = GetHandlers(message, handlerWrapperType, key);
List<object?> 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<object?>)handleMethod.Invoke(handler, new object[] { message, cancellationToken })!;
}
}
}
public async IAsyncEnumerable<TResponse?> HandleManyAsync<TMessage, TResponse>(TMessage message,
object? key = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
where TMessage : notnull
{
List<object?> handlers = GetHandlers<TMessage, TResponse>(message, key);
Type messageType = message.GetType();
Type handlerType = typeof(HandlerWrapper<,>).MakeGenericType(messageType, typeof(TResponse));
key = $"{(key is not null ? $"{key}:" : "")}{handlerType}";
List<object?> 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<TResponse?>)handleMethod.Invoke(handler, new object[] { message, cancellationToken })!;
}
}
}
private List<object?> GetHandlers<TMessage, TResponse>(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<object?> GetHandlers(object message, Type handlerWrapperType, object? key)
private List<object?> GetHandlers(object message,
Type handlerWrapperType,
object? key)
{
Type messageType = message.GetType();
Dictionary<Type, List<object?>> handlers = [];
@@ -145,11 +151,11 @@ public class Mediator(IHandlerProvider handlerProvider,
}
}
IEnumerable<object?> keyedServices = key != null ? provider.GetKeyedServices(handlerWrapperType, key) :
IEnumerable<object?> keyedServices = key is not null ? provider.GetKeyedServices(handlerWrapperType, key) :
provider.GetServices(handlerWrapperType);
AddHandlers(keyedServices);
IEnumerable<object?> additionalHandlers = handlerProvider.Get(messageType, key);
IEnumerable<object?> additionalHandlers = handlerProvider.Get(key);
AddHandlers(additionalHandlers);
return handlers.SelectMany(entry => entry.Value).ToList();
+6 -6
View File
@@ -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<INavigation>();
navigation = requireServiceProvider.Provider.GetRequiredService<INavigation>();
}
if (args.Scope is "new")
{
IServiceScope serviceScope = requireServiceProvider.Provider.CreateScope();
navigationScope = serviceScope.ServiceProvider.GetRequiredService<INavigation>();
navigation = serviceScope.ServiceProvider.GetRequiredService<INavigation>();
}
}
}
if (navigationScope is null)
if (navigation is null)
{
ComponentScopeDescriptor? descriptor = componentScopeProvider.Get(args.Scope ?? scope.Name);
navigationScope = descriptor?.Services?.GetRequiredService<INavigation>();
navigation = descriptor?.Services?.GetRequiredService<INavigation>();
}
navigationScope?.Navigate(args.Route, args.Sender,
navigation?.Navigate(args.Route, args.Sender,
args.Region, args.Navigated, args.Parameters);
return Task.CompletedTask;
+8 -3
View File
@@ -30,10 +30,15 @@ public class Publisher(IHandlerProvider handlerProvider,
Type handlerType = typeof(NotificationHandlerWrapper<>)
.MakeGenericType(notificationType);
List<object?> 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<object?> handlers = [];
foreach (object? handler in handlerProvider.Get(key))
{
handlers.Add(handler);
}
foreach (object? handler in serviceProvider.GetKeyedServices(handlerType, key))
{
handlers.Add(handler);
}
@@ -2,6 +2,7 @@
using Avalonia.Controls.Primitives;
using Avalonia.Xaml.Interactivity;
using Toolkit.Foundation;
using Toolkit.UI.Controls.Avalonia;
namespace Toolkit.UI.Avalonia;