diff --git a/Toolkit.Foundation/HandlerProvider.cs b/Toolkit.Foundation/HandlerProvider.cs index 404a997..caadcde 100644 --- a/Toolkit.Foundation/HandlerProvider.cs +++ b/Toolkit.Foundation/HandlerProvider.cs @@ -4,7 +4,7 @@ public class HandlerProvider(SubscriptionCollection subscriptions) : IHandlerProvider { public IEnumerable Get(Type type, - object key) + object? key = null) { string subscriptionKey = $"{(key is not null ? $"{key}:" : "")}{type}"; if (subscriptions.TryGetValue(subscriptionKey, out List? subscribers)) diff --git a/Toolkit.Foundation/IHandlerProvider.cs b/Toolkit.Foundation/IHandlerProvider.cs index fa01b63..f155b6c 100644 --- a/Toolkit.Foundation/IHandlerProvider.cs +++ b/Toolkit.Foundation/IHandlerProvider.cs @@ -3,6 +3,7 @@ namespace Toolkit.Foundation { public interface IHandlerProvider { - IEnumerable Get(Type type, object key); + IEnumerable Get(Type type, + object? key = null); } } \ No newline at end of file diff --git a/Toolkit.Foundation/IMediator.cs b/Toolkit.Foundation/IMediator.cs index df84e29..3879384 100644 --- a/Toolkit.Foundation/IMediator.cs +++ b/Toolkit.Foundation/IMediator.cs @@ -3,7 +3,11 @@ namespace Toolkit.Foundation { public interface IMediator { - Task Handle(object message, CancellationToken cancellationToken = default); - Task Handle(TRequest request, CancellationToken cancellationToken = default) where TRequest : notnull; + Task Handle(object message, + CancellationToken cancellationToken = default); + + Task Handle(TMessage message, + CancellationToken cancellationToken = default) + where TMessage : notnull; } } \ No newline at end of file diff --git a/Toolkit.Foundation/Mediator.cs b/Toolkit.Foundation/Mediator.cs index 3e9d354..12c625e 100644 --- a/Toolkit.Foundation/Mediator.cs +++ b/Toolkit.Foundation/Mediator.cs @@ -1,27 +1,62 @@ -using System.Reflection; +using Microsoft.Extensions.DependencyInjection; +using System.Reflection; namespace Toolkit.Foundation; -public class Mediator(IServiceProvider provider) : +public class Mediator(IHandlerProvider handlerProvider, + IServiceProvider provider) : IMediator { - public Task Handle(TRequest request, + public async Task Handle(TMessage message, CancellationToken cancellationToken = default) - where TRequest : notnull + where TMessage : notnull { - Type handlerType = typeof(HandlerWrapper<,>).MakeGenericType(request.GetType(), - typeof(TResponse)); + Type messageType = message.GetType(); + Type handlerWrapperType = typeof(HandlerWrapper<,>).MakeGenericType(messageType, typeof(TResponse)); - if (provider.GetService(handlerType) - is object handler) + Dictionary> handlers = []; + + foreach (object? service in provider.GetServices(handlerWrapperType)) { - if (handlerType.GetMethod("Handle") is MethodInfo handleMethod) + if (service?.GetType() is Type serviceType) { - return (Task)handleMethod.Invoke(handler, new object[] { request, cancellationToken })!; + if (!handlers.TryGetValue(serviceType, out List? handlerList)) + { + handlerList = []; + handlers.Add(serviceType, handlerList); + } + + handlerList.Add(service); } } - return Task.FromResult(default); + foreach (object? handler in handlerProvider.Get(messageType)) + { + if (handler is not null) + { + Type handlerType = handler.GetType(); + if (!handlers.TryGetValue(handlerType, out List? handlerList)) + { + handlerList = []; + handlers.Add(handlerType, handlerList); + } + handlerList.Add(handler); + } + } + + foreach (KeyValuePair> handlerEntry in handlers) + { + foreach (object? handler in handlerEntry.Value) + { + if (handler?.GetType().GetMethod("Handle") is MethodInfo handleMethod) + { + return await (Task)handleMethod.Invoke(handler, + new object[] { message, cancellationToken })!; + } + } + } + + return default; } public Task Handle(object message, diff --git a/Toolkit.Foundation/Publisher.cs b/Toolkit.Foundation/Publisher.cs index ccaa823..cecca5c 100644 --- a/Toolkit.Foundation/Publisher.cs +++ b/Toolkit.Foundation/Publisher.cs @@ -25,12 +25,11 @@ public class Publisher(IHandlerProvider handlerProvider, object? key = null) { Type notificationType = message.GetType(); + Type handlerType = typeof(NotificationHandlerWrapper<>) + .MakeGenericType(notificationType); - List handlers = provider.GetServices(typeof(NotificationHandlerWrapper<>) - .MakeGenericType(notificationType)).ToList(); - - foreach (object? handler in handlerProvider - .Get(notificationType, key!)) + List handlers = provider.GetServices(handlerType).ToList(); + foreach (object? handler in handlerProvider.Get(notificationType, key)) { handlers.Add(handler); } @@ -39,8 +38,7 @@ public class Publisher(IHandlerProvider handlerProvider, { if (handler is not null) { - Type? handlerType = handler.GetType(); - MethodInfo? handleMethod = handlerType.GetMethod("Handle", + MethodInfo? handleMethod = handler.GetType().GetMethod("Handle", [notificationType]); if (handleMethod is not null) diff --git a/Toolkit.Foundation/Subscription.cs b/Toolkit.Foundation/Subscription.cs index 1905d52..299b9d9 100644 --- a/Toolkit.Foundation/Subscription.cs +++ b/Toolkit.Foundation/Subscription.cs @@ -76,6 +76,11 @@ public class Subscription(SubscriptionCollection subscriptions, ? handler.GetPropertyValue(() => attribute.Key) is { } value ? value : attribute.Key : null; private IEnumerable GetHandlerInterfaces(Type handlerType) => - handlerType.GetInterfaces().Where(interfaceType => interfaceType.IsGenericType && - interfaceType.GetGenericTypeDefinition() == typeof(INotificationHandler<>)); + handlerType.GetInterfaces().Where(interfaceType => + { + Type? definition = interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : null; + return definition == typeof(INotificationHandler<>) || + definition == typeof(IHandler<>) || + definition == typeof(IHandler<,>); + }); } \ No newline at end of file