Add supported for key mediator handelrs

This commit is contained in:
TheXamlGuy
2024-06-02 15:00:59 +01:00
parent c24538f545
commit 48b33416c9
7 changed files with 104 additions and 39 deletions
-3
View File
@@ -1,3 +0,0 @@
namespace Toolkit.Foundation;
public class AggerateAttribute(Type type, object key) : NotificationAttribute(type, key);
+2 -2
View File
@@ -2,9 +2,9 @@
public record Aggregate public record Aggregate
{ {
public static AggregateEventArgs<TValue, TOptions> As<TValue, TOptions>(TOptions options) public static AggerateEventArgs<TValue, TOptions> As<TValue, TOptions>(TOptions options)
where TOptions : class => new(options); where TOptions : class => new(options);
public static AggerateEventArgs<TValue> As<TValue>() => public static AggerateEventArgs<TValue> As<TValue>() =>
new AggerateEventArgs<TValue>(); new();
} }
+3 -4
View File
@@ -1,8 +1,7 @@
namespace Toolkit.Foundation; namespace Toolkit.Foundation;
public record AggregateEventArgs<TValue, TOptions>(TOptions? Options = null) : public record AggerateEventArgs<TType, TValue>(TValue? Value = default) :
IAggregate IAggregate;
where TOptions : class;
public record AggerateEventArgs<TValue> : public record AggerateEventArgs<TType> :
IAggregate; IAggregate;
+2
View File
@@ -3,9 +3,11 @@
public interface IMediator public interface IMediator
{ {
Task<object?> Handle(object message, Task<object?> Handle(object message,
object? key = null,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);
Task<TResponse?> Handle<TMessage, TResponse>(TMessage message, Task<TResponse?> Handle<TMessage, TResponse>(TMessage message,
object? key = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
where TMessage : notnull; where TMessage : notnull;
} }
@@ -57,12 +57,12 @@ public static class IServiceCollectionExtensions
if (key is not null) if (key is not null)
{ {
services.TryAdd(new ServiceDescriptor(typeof(INotificationHandler<>) services.Add(new ServiceDescriptor(typeof(INotificationHandler<>)
.MakeGenericType(notificationType), key, typeof(THandler), lifetime)); .MakeGenericType(notificationType), key, typeof(THandler), lifetime));
} }
else else
{ {
services.TryAdd(new ServiceDescriptor(typeof(INotificationHandler<>) services.Add(new ServiceDescriptor(typeof(INotificationHandler<>)
.MakeGenericType(notificationType), typeof(THandler), lifetime)); .MakeGenericType(notificationType), typeof(THandler), lifetime));
} }
@@ -94,14 +94,34 @@ public static class IServiceCollectionExtensions
Type wrapperType = typeof(HandlerWrapper<,>) Type wrapperType = typeof(HandlerWrapper<,>)
.MakeGenericType(requestType, responseType); .MakeGenericType(requestType, responseType);
services.TryAdd(new ServiceDescriptor(typeof(THandler), if (key is not null)
typeof(THandler), lifetime)); {
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 => if (key is not null)
provider.GetService<IServiceFactory>()?.Create(wrapperType, {
provider.GetRequiredService<THandler>(),
provider.GetServices(typeof(IPipelineBehaviour<,>) services.Add(new ServiceDescriptor(wrapperType, key, (provider, key) =>
.MakeGenericType(requestType, responseType)))!, lifetime)); provider.GetService<IServiceFactory>()?.Create(wrapperType,
provider.GetRequiredKeyedService<THandler>(key),
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));
}
} }
} }
+53 -13
View File
@@ -8,17 +8,19 @@ public class Mediator(IHandlerProvider handlerProvider,
IMediator IMediator
{ {
public async Task<TResponse?> Handle<TMessage, TResponse>(TMessage message, public async Task<TResponse?> Handle<TMessage, TResponse>(TMessage message,
object? key = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
where TMessage : notnull where TMessage : notnull
{ {
Type messageType = message.GetType(); Type messageType = message.GetType();
Type handlerWrapperType = typeof(HandlerWrapper<,>).MakeGenericType(messageType, typeof(TResponse)); Type handlerWrapperType = typeof(HandlerWrapper<,>).MakeGenericType(messageType,
typeof(TResponse));
Dictionary<Type, List<object?>> handlers = []; Dictionary<Type, List<object?>> handlers = [];
foreach (object? handler in key is not null ? provider.GetKeyedServices(handlerWrapperType, key) :
foreach (object? service in provider.GetServices(handlerWrapperType)) provider.GetServices(handlerWrapperType))
{ {
if (service?.GetType() is Type serviceType) if (handler?.GetType() is Type serviceType)
{ {
if (!handlers.TryGetValue(serviceType, out List<object?>? handlerList)) if (!handlers.TryGetValue(serviceType, out List<object?>? handlerList))
{ {
@@ -26,7 +28,7 @@ public class Mediator(IHandlerProvider handlerProvider,
handlers.Add(serviceType, handlerList); handlers.Add(serviceType, handlerList);
} }
handlerList.Add(service); handlerList.Add(handler);
} }
} }
@@ -60,26 +62,64 @@ public class Mediator(IHandlerProvider handlerProvider,
return default; return default;
} }
public Task<object?> Handle(object message, public async Task<object?> Handle(object message,
object? key = null,
CancellationToken cancellationToken = default) 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) requestType.GetGenericArguments().Length == 1)
{ {
Type responseType = requestType.GetGenericArguments()[0]; Type responseType = requestType.GetGenericArguments()[0];
Type handlerType = typeof(HandlerWrapper<,>).MakeGenericType(message.GetType(), Type handlerWrapperType = typeof(HandlerWrapper<,>).MakeGenericType(message.GetType(),
responseType); responseType);
if (provider.GetService(handlerType) Dictionary<Type, List<object?>> handlers = [];
is object handler)
foreach (object? handler in handlerProvider.Get(messageType))
{ {
if (handlerType.GetMethod("Handle") is MethodInfo handleMethod) if (handler is not null)
{ {
return (Task<object?>)handleMethod.Invoke(handler, new object[] { message, cancellationToken })!; Type handlerType = handler.GetType();
if (!handlers.TryGetValue(handlerType, out List<object?>? 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<object?>? handlerList))
{
handlerList = [];
handlers.Add(serviceType, handlerList);
}
handlerList.Add(handler);
}
}
foreach (KeyValuePair<Type, List<object?>> handlerEntry in handlers)
{
foreach (object? handler in handlerEntry.Value)
{
if (handler?.GetType().GetMethod("Handle", [messageType, typeof(CancellationToken)]) is MethodInfo handleMethod)
{
return await(Task<object?>)handleMethod.Invoke(handler,
new object[] { message, cancellationToken })!;
}
} }
} }
} }
return Task.FromResult<object?>(default); return default;
} }
} }
+15 -8
View File
@@ -199,12 +199,22 @@ public partial class ObservableCollection<TItem> :
Clear(); Clear();
} }
AggregateExpression expression = CreateAggregateExpression(); AggregateExpression expression = BuildAggregateExpression();
Publisher.PublishUI(expression.Value, expression.Key);
}
public void Fetch(Func<AggregateExpression> aggregateDelegate,
bool reset = false)
{
if (reset)
{
Clear();
}
AggregateExpression expression = aggregateDelegate.Invoke();
Publisher.PublishUI(expression.Value, expression.Key); Publisher.PublishUI(expression.Value, expression.Key);
} }
protected virtual IAggregate OnAggerate() =>
new AggerateEventArgs<TItem>();
public void Clear() public void Clear()
{ {
@@ -565,11 +575,8 @@ public partial class ObservableCollection<TItem> :
collection.Insert(index > Count ? Count : index, item); collection.Insert(index > Count ? Count : index, item);
} }
protected virtual AggregateExpression CreateAggregateExpression() => protected virtual AggregateExpression BuildAggregateExpression() =>
new AggregateExpression(new AggerateEventArgs<TItem>()); new(new AggerateEventArgs<TItem>());
protected virtual object? CreateAggregationKey() =>
default;
protected virtual void RemoveItem(int index) => protected virtual void RemoveItem(int index) =>
collection.RemoveAt(index); collection.RemoveAt(index);