Add supported for key mediator handelrs
This commit is contained in:
@@ -1,3 +0,0 @@
|
|||||||
namespace Toolkit.Foundation;
|
|
||||||
|
|
||||||
public class AggerateAttribute(Type type, object key) : NotificationAttribute(type, key);
|
|
||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<TType> :
|
||||||
public record AggerateEventArgs<TValue> :
|
|
||||||
IAggregate;
|
IAggregate;
|
||||||
@@ -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,9 +94,28 @@ 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)
|
||||||
|
{
|
||||||
|
services.Add(new ServiceDescriptor(typeof(THandler), key,
|
||||||
typeof(THandler), lifetime));
|
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) =>
|
||||||
|
provider.GetService<IServiceFactory>()?.Create(wrapperType,
|
||||||
|
provider.GetRequiredKeyedService<THandler>(key),
|
||||||
|
provider.GetServices(typeof(IPipelineBehaviour<,>)
|
||||||
|
.MakeGenericType(requestType, responseType)))!, lifetime));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
services.Add(new ServiceDescriptor(wrapperType, provider =>
|
services.Add(new ServiceDescriptor(wrapperType, provider =>
|
||||||
provider.GetService<IServiceFactory>()?.Create(wrapperType,
|
provider.GetService<IServiceFactory>()?.Create(wrapperType,
|
||||||
provider.GetRequiredService<THandler>(),
|
provider.GetRequiredService<THandler>(),
|
||||||
@@ -104,6 +123,7 @@ public static class IServiceCollectionExtensions
|
|||||||
.MakeGenericType(requestType, responseType)))!, lifetime));
|
.MakeGenericType(requestType, responseType)))!, lifetime));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user