diff --git a/Toolkit.Foundation/AggerateAttribute.cs b/Toolkit.Foundation/AggerateAttribute.cs deleted file mode 100644 index 36bc641..0000000 --- a/Toolkit.Foundation/AggerateAttribute.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Toolkit.Foundation; - -public class AggerateAttribute(Type type, object key) : NotificationAttribute(type, key); \ No newline at end of file diff --git a/Toolkit.Foundation/Aggregate.cs b/Toolkit.Foundation/Aggregate.cs index ebbd1df..b051bc9 100644 --- a/Toolkit.Foundation/Aggregate.cs +++ b/Toolkit.Foundation/Aggregate.cs @@ -2,9 +2,9 @@ public record Aggregate { - public static AggregateEventArgs As(TOptions options) + public static AggerateEventArgs As(TOptions options) where TOptions : class => new(options); public static AggerateEventArgs As() => - new AggerateEventArgs(); + new(); } diff --git a/Toolkit.Foundation/AggregateEventArgs.cs b/Toolkit.Foundation/AggregateEventArgs.cs index 9c4a6b2..eff0223 100644 --- a/Toolkit.Foundation/AggregateEventArgs.cs +++ b/Toolkit.Foundation/AggregateEventArgs.cs @@ -1,8 +1,7 @@ namespace Toolkit.Foundation; -public record AggregateEventArgs(TOptions? Options = null) : - IAggregate - where TOptions : class; +public record AggerateEventArgs(TValue? Value = default) : + IAggregate; -public record AggerateEventArgs : +public record AggerateEventArgs : IAggregate; \ No newline at end of file diff --git a/Toolkit.Foundation/IMediator.cs b/Toolkit.Foundation/IMediator.cs index 3d720bc..4af4be9 100644 --- a/Toolkit.Foundation/IMediator.cs +++ b/Toolkit.Foundation/IMediator.cs @@ -3,9 +3,11 @@ public interface IMediator { Task Handle(object message, + object? key = null, CancellationToken cancellationToken = default); Task Handle(TMessage message, + object? key = null, CancellationToken cancellationToken = default) where TMessage : notnull; } diff --git a/Toolkit.Foundation/IServiceCollectionExtensions.cs b/Toolkit.Foundation/IServiceCollectionExtensions.cs index 77b229f..a5a779f 100644 --- a/Toolkit.Foundation/IServiceCollectionExtensions.cs +++ b/Toolkit.Foundation/IServiceCollectionExtensions.cs @@ -57,12 +57,12 @@ public static class IServiceCollectionExtensions if (key is not null) { - services.TryAdd(new ServiceDescriptor(typeof(INotificationHandler<>) + services.Add(new ServiceDescriptor(typeof(INotificationHandler<>) .MakeGenericType(notificationType), key, typeof(THandler), lifetime)); } else { - services.TryAdd(new ServiceDescriptor(typeof(INotificationHandler<>) + services.Add(new ServiceDescriptor(typeof(INotificationHandler<>) .MakeGenericType(notificationType), typeof(THandler), lifetime)); } @@ -94,14 +94,34 @@ public static class IServiceCollectionExtensions Type wrapperType = typeof(HandlerWrapper<,>) .MakeGenericType(requestType, responseType); - services.TryAdd(new ServiceDescriptor(typeof(THandler), - typeof(THandler), lifetime)); + 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(wrapperType, provider => - provider.GetService()?.Create(wrapperType, - provider.GetRequiredService(), - provider.GetServices(typeof(IPipelineBehaviour<,>) - .MakeGenericType(requestType, responseType)))!, 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)); + } } } diff --git a/Toolkit.Foundation/Mediator.cs b/Toolkit.Foundation/Mediator.cs index 6e50028..c47a009 100644 --- a/Toolkit.Foundation/Mediator.cs +++ b/Toolkit.Foundation/Mediator.cs @@ -8,17 +8,19 @@ public class Mediator(IHandlerProvider handlerProvider, IMediator { public async Task Handle(TMessage message, + object? key = null, CancellationToken cancellationToken = default) where TMessage : notnull { Type messageType = message.GetType(); - Type handlerWrapperType = typeof(HandlerWrapper<,>).MakeGenericType(messageType, typeof(TResponse)); + Type handlerWrapperType = typeof(HandlerWrapper<,>).MakeGenericType(messageType, + typeof(TResponse)); Dictionary> handlers = []; - - foreach (object? service in provider.GetServices(handlerWrapperType)) + foreach (object? handler in key is not null ? provider.GetKeyedServices(handlerWrapperType, key) : + provider.GetServices(handlerWrapperType)) { - if (service?.GetType() is Type serviceType) + if (handler?.GetType() is Type serviceType) { if (!handlers.TryGetValue(serviceType, out List? handlerList)) { @@ -26,7 +28,7 @@ public class Mediator(IHandlerProvider handlerProvider, handlers.Add(serviceType, handlerList); } - handlerList.Add(service); + handlerList.Add(handler); } } @@ -60,26 +62,64 @@ public class Mediator(IHandlerProvider handlerProvider, return default; } - public Task Handle(object message, + public async Task Handle(object message, + object? key = null, CancellationToken cancellationToken = default) { - if (message.GetType().GetInterface(message.GetType().Name) is Type requestType && + Type messageType = message.GetType(); + + if (messageType.GetInterface(message.GetType().Name) is Type requestType && requestType.GetGenericArguments().Length == 1) { Type responseType = requestType.GetGenericArguments()[0]; - Type handlerType = typeof(HandlerWrapper<,>).MakeGenericType(message.GetType(), + Type handlerWrapperType = typeof(HandlerWrapper<,>).MakeGenericType(message.GetType(), responseType); - if (provider.GetService(handlerType) - is object handler) + Dictionary> handlers = []; + + foreach (object? handler in handlerProvider.Get(messageType)) { - if (handlerType.GetMethod("Handle") is MethodInfo handleMethod) + if (handler is not null) { - return (Task)handleMethod.Invoke(handler, new object[] { message, cancellationToken })!; + Type handlerType = handler.GetType(); + if (!handlers.TryGetValue(handlerType, out List? handlerList)) + { + handlerList = []; + handlers.Add(handlerType, handlerList); + } + + handlerList.Add(handler); + } + } + + foreach (object? handler in key is not null ? provider.GetKeyedServices(handlerWrapperType, key) : + provider.GetServices(handlerWrapperType)) + { + if (handler?.GetType() is Type serviceType) + { + if (!handlers.TryGetValue(serviceType, out List? handlerList)) + { + handlerList = []; + handlers.Add(serviceType, handlerList); + } + + handlerList.Add(handler); + } + } + + foreach (KeyValuePair> handlerEntry in handlers) + { + foreach (object? handler in handlerEntry.Value) + { + if (handler?.GetType().GetMethod("Handle", [messageType, typeof(CancellationToken)]) is MethodInfo handleMethod) + { + return await(Task)handleMethod.Invoke(handler, + new object[] { message, cancellationToken })!; + } } } } - return Task.FromResult(default); + return default; } } \ No newline at end of file diff --git a/Toolkit.Foundation/ObservableCollection.cs b/Toolkit.Foundation/ObservableCollection.cs index 67891bd..e65f0c1 100644 --- a/Toolkit.Foundation/ObservableCollection.cs +++ b/Toolkit.Foundation/ObservableCollection.cs @@ -199,12 +199,22 @@ public partial class ObservableCollection : Clear(); } - AggregateExpression expression = CreateAggregateExpression(); + AggregateExpression expression = BuildAggregateExpression(); + Publisher.PublishUI(expression.Value, expression.Key); + } + + public void Fetch(Func aggregateDelegate, + bool reset = false) + { + if (reset) + { + Clear(); + } + + AggregateExpression expression = aggregateDelegate.Invoke(); Publisher.PublishUI(expression.Value, expression.Key); } - protected virtual IAggregate OnAggerate() => - new AggerateEventArgs(); public void Clear() { @@ -565,11 +575,8 @@ public partial class ObservableCollection : collection.Insert(index > Count ? Count : index, item); } - protected virtual AggregateExpression CreateAggregateExpression() => - new AggregateExpression(new AggerateEventArgs()); - - protected virtual object? CreateAggregationKey() => - default; + protected virtual AggregateExpression BuildAggregateExpression() => + new(new AggerateEventArgs()); protected virtual void RemoveItem(int index) => collection.RemoveAt(index);