This commit is contained in:
Dan Clark
2024-11-25 14:27:17 +00:00
parent f7a96b3784
commit bb9e796600
10 changed files with 96 additions and 122 deletions
@@ -1,3 +0,0 @@
namespace Toolkit.Foundation;
public delegate Task<TResponse> AsyncHandlerDelegate<TResponse>();
@@ -19,16 +19,11 @@ public class AsyncHandlerInitialization<TMessage, TResponse, THandler>(IServiceP
foreach (IAsyncHandler<TMessage, TResponse> handler in handlers) foreach (IAsyncHandler<TMessage, TResponse> handler in handlers)
{ {
AsyncHandlerDelegate<TResponse> handlerDelegate = () => Task<TResponse> ExecutePipeline(int index) =>index < 0
handler.Handle(args.Message, args.CancellationToken); ? handler.Handle(args.Message, args.CancellationToken)
: behaviors.ElementAt(index).Handle(args.Message, () => ExecutePipeline(index - 1));
foreach (IAsyncPipelineBehavior<TMessage, TResponse>? behavior in behaviors.Reverse()) args.Reply(ExecutePipeline(behaviors.Count() - 1));
{
AsyncHandlerDelegate<TResponse> next = handlerDelegate;
handlerDelegate = () => behavior.Handle(args.Message, next);
}
args.Reply(handlerDelegate());
} }
}); });
} }
@@ -47,21 +42,15 @@ public class AsyncHandlerInitialization<TMessage, THandler>(IServiceProvider pro
(provider, args) => (provider, args) =>
{ {
IEnumerable<IAsyncHandler<TMessage>> handlers = provider.GetServices<IAsyncHandler<TMessage>>(); IEnumerable<IAsyncHandler<TMessage>> handlers = provider.GetServices<IAsyncHandler<TMessage>>();
IEnumerable<IAsyncPipelineBehavior<TMessage, Unit>> behaviors = provider.GetServices<IAsyncPipelineBehavior<TMessage, Unit>>(); IEnumerable<IAsyncPipelineBehavior<TMessage>> behaviors = provider.GetServices<IAsyncPipelineBehavior<TMessage>>();
foreach (IAsyncHandler<TMessage> handler in handlers) foreach (IAsyncHandler<TMessage> handler in handlers)
{ {
AsyncHandlerDelegate<Unit> handlerDelegate = () => Task<Unit> ExecutePipeline(int index) => index < 0
handler.Handle(args.Message, args.CancellationToken).ContinueWith(_ => Unit.Value); ? handler.Handle(args.Message, args.CancellationToken).ContinueWith(_ => Unit.Value)
: behaviors.ElementAt(index).Handle(args.Message, () => ExecutePipeline(index - 1)).ContinueWith(_ => Unit.Value);
foreach (IAsyncPipelineBehavior<TMessage, Unit> behavior in behaviors.Reverse()) args.Reply(ExecutePipeline(behaviors.Count() - 1));
{
AsyncHandlerDelegate<Unit> next = handlerDelegate;
handlerDelegate = () => behavior.Handle(args.Message, next);
}
handlerDelegate();
args.Reply(Unit.Value);
} }
}); });
} }
@@ -15,21 +15,15 @@ public class AsyncHandlerKeyedInitialization<TMessage, THandler>(string key, ISe
(provider, args) => (provider, args) =>
{ {
IEnumerable<IAsyncHandler<TMessage>> handlers = provider.GetKeyedServices<IAsyncHandler<TMessage>>(key); IEnumerable<IAsyncHandler<TMessage>> handlers = provider.GetKeyedServices<IAsyncHandler<TMessage>>(key);
IEnumerable<IAsyncPipelineBehavior<TMessage, Unit>> behaviors = provider.GetServices<IAsyncPipelineBehavior<TMessage, Unit>>(); IEnumerable<IAsyncPipelineBehavior<TMessage>> behaviors = provider.GetKeyedServices<IAsyncPipelineBehavior<TMessage>>(key);
foreach (IAsyncHandler<TMessage> handler in handlers) foreach (IAsyncHandler<TMessage> handler in handlers)
{ {
AsyncHandlerDelegate<Unit> handlerDelegate = () => Task<Unit> ExecutePipeline(int index) => index < 0
handler.Handle(args.Message, args.CancellationToken).ContinueWith(_ => Unit.Value); ? handler.Handle(args.Message, args.CancellationToken).ContinueWith(_ => Unit.Value)
: behaviors.ElementAt(index).Handle(args.Message, () => ExecutePipeline(index - 1)).ContinueWith(_ => Unit.Value);
foreach (IAsyncPipelineBehavior<TMessage, Unit> behavior in behaviors.Reverse()) args.Reply(ExecutePipeline(behaviors.Count() - 1));
{
AsyncHandlerDelegate<Unit> next = handlerDelegate;
handlerDelegate = () => behavior.Handle(args.Message, next);
}
handlerDelegate();
args.Reply(Unit.Value);
} }
}); });
} }
@@ -48,22 +42,17 @@ public class AsyncHandlerKeyedInitialization<TMessage, TResponse, THandler>(stri
(provider, args) => (provider, args) =>
{ {
IEnumerable<IAsyncHandler<TMessage, TResponse>> handlers = provider.GetKeyedServices<IAsyncHandler<TMessage, TResponse>>(key); IEnumerable<IAsyncHandler<TMessage, TResponse>> handlers = provider.GetKeyedServices<IAsyncHandler<TMessage, TResponse>>(key);
IEnumerable<IAsyncPipelineBehavior<TMessage, TResponse>> behaviors = provider.GetServices<IAsyncPipelineBehavior<TMessage, TResponse>>(); IEnumerable<IAsyncPipelineBehavior<TMessage, TResponse>> behaviors = provider.GetKeyedServices<IAsyncPipelineBehavior<TMessage, TResponse>>(key);
foreach (IAsyncHandler<TMessage, TResponse> handler in handlers) foreach (IAsyncHandler<TMessage, TResponse> handler in handlers)
{ {
AsyncHandlerDelegate<TResponse> handlerDelegate = () => Task<TResponse> ExecutePipeline(int index) => index < 0
handler.Handle(args.Message, args.CancellationToken); ? handler.Handle(args.Message, args.CancellationToken)
: behaviors.ElementAt(index).Handle(args.Message, () => ExecutePipeline(index - 1));
foreach (IAsyncPipelineBehavior<TMessage, TResponse> behavior in behaviors.Reverse()) args.Reply(ExecutePipeline(behaviors.Count() - 1));
{
AsyncHandlerDelegate<TResponse> next = handlerDelegate;
handlerDelegate = () => behavior.Handle(args.Message, next);
}
args.Reply(handlerDelegate());
} }
}); });
} }
} }
} }
-3
View File
@@ -1,3 +0,0 @@
namespace Toolkit.Foundation;
public delegate TResponse HandlerDelegate<TResponse>();
+21 -27
View File
@@ -17,28 +17,20 @@ public class HandlerInitialization<TMessage, TResponse, THandler>(IServiceProvid
IEnumerable<IHandler<TMessage, TResponse>> handlers = provider.GetServices<IHandler<TMessage, TResponse>>(); IEnumerable<IHandler<TMessage, TResponse>> handlers = provider.GetServices<IHandler<TMessage, TResponse>>();
IEnumerable<IPipelineBehavior<TMessage, TResponse>> behaviors = provider.GetServices<IPipelineBehavior<TMessage, TResponse>>(); IEnumerable<IPipelineBehavior<TMessage, TResponse>> behaviors = provider.GetServices<IPipelineBehavior<TMessage, TResponse>>();
HandlerDelegate<TResponse> handlerDelegate = () => foreach (IHandler<TMessage, TResponse> handler in handlers)
{ {
TResponse response = default!; TResponse ExecutePipeline(int index) => index < 0
foreach (IHandler<TMessage, TResponse> handler in handlers) ? handler.Handle(args.Message)
{ : behaviors.ElementAt(index).Handle(args.Message, () => ExecutePipeline(index - 1));
response = handler.Handle(args.Message);
}
return response;
};
foreach (IPipelineBehavior<TMessage, TResponse> behavior in behaviors.Reverse()) ExecutePipeline(behaviors.Count() - 1);
{
HandlerDelegate<TResponse> next = handlerDelegate;
handlerDelegate = () => behavior.Handle(args.Message, next);
} }
handlerDelegate();
}); });
} }
} }
} }
public class HandlerInitialization<TMessage, THandler>(IServiceProvider provider) : public class HandlerInitialization<TMessage, THandler>(IServiceProvider provider) :
IInitialization where THandler : class, IHandler<TMessage> IInitialization where THandler : class, IHandler<TMessage>
where TMessage : class where TMessage : class
@@ -51,26 +43,28 @@ public class HandlerInitialization<TMessage, THandler>(IServiceProvider provider
(provider, args) => (provider, args) =>
{ {
IEnumerable<IHandler<TMessage>> handlers = provider.GetServices<IHandler<TMessage>>(); IEnumerable<IHandler<TMessage>> handlers = provider.GetServices<IHandler<TMessage>>();
IEnumerable<IPipelineBehavior<TMessage, Unit>> behaviors = provider.GetServices<IPipelineBehavior<TMessage, Unit>>(); IEnumerable<IPipelineBehavior<TMessage>> behaviors = provider.GetServices<IPipelineBehavior<TMessage>>();
HandlerDelegate<Unit> handlerDelegate = () => foreach (IHandler<TMessage> handler in handlers)
{ {
foreach (IHandler<TMessage> handler in handlers) void ExecutePipeline(int index)
{ {
handler.Handle(args); if (index < 0)
{
handler.Handle(args);
return;
}
behaviors.ElementAt(index).Handle(args, () =>
{
ExecutePipeline(index - 1);
return Unit.Value;
});
} }
return Unit.Value;
};
foreach (IPipelineBehavior<TMessage, Unit> behavior in behaviors.Reverse()) ExecutePipeline(behaviors.Count() - 1);
{
HandlerDelegate<Unit> next = handlerDelegate;
handlerDelegate = () => behavior.Handle(args, next);
} }
handlerDelegate();
}); });
} }
} }
} }
@@ -15,30 +15,32 @@ public class HandlerKeyedInitialization<TMessage, THandler>(string key, IService
(provider, args) => (provider, args) =>
{ {
IEnumerable<IHandler<TMessage>> handlers = provider.GetKeyedServices<IHandler<TMessage>>(key); IEnumerable<IHandler<TMessage>> handlers = provider.GetKeyedServices<IHandler<TMessage>>(key);
IEnumerable<IPipelineBehavior<TMessage, Unit>> behaviors = provider.GetServices<IPipelineBehavior<TMessage, Unit>>(); IEnumerable<IPipelineBehavior<TMessage>> behaviors = provider.GetServices<IPipelineBehavior<TMessage>>();
HandlerDelegate<Unit> handlerDelegate = () => foreach (IHandler<TMessage> handler in handlers)
{ {
foreach (IHandler<TMessage> handler in handlers) void ExecutePipeline(int index)
{ {
handler.Handle(args); if (index < 0)
{
handler.Handle(args);
return;
}
behaviors.ElementAt(index).Handle(args, () =>
{
ExecutePipeline(index - 1);
return Unit.Value;
});
} }
return Unit.Value;
};
foreach (IPipelineBehavior<TMessage, Unit> behavior in behaviors.Reverse()) ExecutePipeline(behaviors.Count() - 1);
{
HandlerDelegate<Unit> next = handlerDelegate;
handlerDelegate = () => behavior.Handle(args, next);
} }
handlerDelegate();
}); });
} }
} }
} }
public class HandlerKeyedInitialization<TMessage, TResponse, THandler>(string key, IServiceProvider provider) : public class HandlerKeyedInitialization<TMessage, TResponse, THandler>(string key, IServiceProvider provider) :
IInitialization where THandler : class, IHandler<TMessage, TResponse> IInitialization where THandler : class, IHandler<TMessage, TResponse>
where TMessage : class where TMessage : class
@@ -53,24 +55,15 @@ public class HandlerKeyedInitialization<TMessage, TResponse, THandler>(string ke
IEnumerable<IHandler<TMessage, TResponse>> handlers = provider.GetKeyedServices<IHandler<TMessage, TResponse>>(key); IEnumerable<IHandler<TMessage, TResponse>> handlers = provider.GetKeyedServices<IHandler<TMessage, TResponse>>(key);
IEnumerable<IPipelineBehavior<TMessage, TResponse>> behaviors = provider.GetServices<IPipelineBehavior<TMessage, TResponse>>(); IEnumerable<IPipelineBehavior<TMessage, TResponse>> behaviors = provider.GetServices<IPipelineBehavior<TMessage, TResponse>>();
HandlerDelegate<TResponse> handlerDelegate = () => foreach (IHandler<TMessage, TResponse> handler in handlers)
{ {
TResponse response = default!; TResponse ExecutePipeline(int index) => index < 0
foreach (IHandler<TMessage, TResponse> handler in handlers) ? handler.Handle(args.Message)
{ : behaviors.ElementAt(index).Handle(args.Message, () => ExecutePipeline(index - 1));
response = handler.Handle(args.Message);
}
return response;
};
foreach (IPipelineBehavior<TMessage, TResponse> behavior in behaviors.Reverse()) ExecutePipeline(behaviors.Count() - 1);
{
HandlerDelegate<TResponse> next = handlerDelegate;
handlerDelegate = () => behavior.Handle(args.Message, next);
} }
handlerDelegate();
}); });
} }
} }
} }
+4 -2
View File
@@ -3,11 +3,13 @@
public interface IAsyncHandler<TMessage, TResponse> : public interface IAsyncHandler<TMessage, TResponse> :
IHandler IHandler
{ {
Task<TResponse> Handle(TMessage args, CancellationToken cancellationToken = default); Task<TResponse> Handle(TMessage args,
CancellationToken cancellationToken = default);
} }
public interface IAsyncHandler<TMessage> : public interface IAsyncHandler<TMessage> :
IHandler IHandler
{ {
Task Handle(TMessage args, CancellationToken cancellationToken = default); Task Handle(TMessage args,
CancellationToken cancellationToken = default);
} }
+8 -2
View File
@@ -1,8 +1,14 @@
namespace Toolkit.Foundation; namespace Toolkit.Foundation;
public interface IAsyncPipelineBehavior<TMessage, public interface IAsyncPipelineBehavior<TMessage,
TResponse> TResponse>
{ {
Task<TResponse> Handle(TMessage message, Task<TResponse> Handle(TMessage message,
AsyncHandlerDelegate<TResponse> next); Func<Task<TResponse>> next);
}
public interface IAsyncPipelineBehavior<TMessage>
{
Task Handle(TMessage message,
Func<Task> next);
} }
+8 -3
View File
@@ -1,9 +1,14 @@
namespace Toolkit.Foundation; namespace Toolkit.Foundation;
public interface IPipelineBehavior<TMessage, public interface IPipelineBehavior<TMessage,
TResponse> TResponse>
{ {
TResponse Handle(TMessage message, TResponse Handle(TMessage message,
HandlerDelegate<TResponse> next); Func<TResponse> next);
} }
public interface IPipelineBehavior<TMessage>
{
void Handle(TMessage message,
Func<Unit> next);
}
@@ -163,23 +163,25 @@ public static class IServiceCollectionExtensions
where TInitialization : class, where TInitialization : class,
IInitialization IInitialization
{ {
services.AddTransient<IInitialization>(provider => provider.GetRequiredService<IServiceFactory>().Create<TInitialization>(parameters)); services.AddTransient<IInitialization>(provider => provider.GetRequiredService<IServiceFactory>()
.Create<TInitialization>(parameters));
return services; return services;
} }
public static IServiceCollection AddAsyncPipelineBehavior<TMessage, TResponse, TBehavior>(this IServiceCollection services) public static IServiceCollection AddAsyncPipelineBehavior(this IServiceCollection services,
where TBehavior : class, Type behaviorType,
IAsyncPipelineBehavior<TMessage, TResponse> string? key = null)
{ {
services.AddTransient<IAsyncPipelineBehavior<TMessage, TResponse>, TBehavior>(); if (key is { Length: > 0 })
return services; {
} services.AddKeyedTransient(typeof(IAsyncPipelineBehavior<>), key, behaviorType);
}
else
{
services.AddTransient(typeof(IAsyncPipelineBehavior<>), behaviorType);
}
public static IServiceCollection AddPipelineBehavior<TMessage, TResponse, TBehavior>(this IServiceCollection services)
where TBehavior : class,
IPipelineBehavior<TMessage, TResponse>
{
services.AddTransient<IPipelineBehavior<TMessage, TResponse>, TBehavior>();
return services; return services;
} }