Open ivanpaulovich opened 5 years ago
I'm trying to implement this. Here's some code how it may work
services.AddFluentMediator(m =>
{
m.On<PingRequest>().PipelineAsync()
.Return<PingResponse, IPingHandler>(
(handler, req) => handler.MyCustomFooBarAsync(req))
.WithContinuation<PingResponse>() // returns IPipelineAsyncBuilder<PingResponse>
.Return<SecondPingResponse, ISecondPingHandler>(
(ISecondPingHandler handler, PingResponse req) => handler.MySecondFooBarAsync(req));
});
// ... some code ...
var response = await mediator.SendAsync<SecondPingResponse>(ping); // We specify the last type from pipe chain
In Pipeline.cs
// ... some code ...
private readonly IPipelineAsync? _nestedPipe;
// ... some code ...
public Pipeline(IMethodCollection<Method<Func<object, object, Task>>> methods, IDirect? direct, Type requestType, string? name, IPipelineAsync? nestedPipe)
{
_methods = methods;
_direct = direct;
RequestType = requestType;
Name = name;
_nestedPipe = nestedPipe;
}
public async Task<TResult> SendAsync<TResult>(GetService getService, object request)
{
if (_direct is null)
{
throw new ReturnFunctionIsNullException("The return function is null. SendAsync<TResult> method not executed.");
}
foreach (var handler in _methods.GetMethods())
{
var concreteHandler = getService(handler.HandlerType);
await handler.Action(concreteHandler, request);
}
// NOTE: should we return object to avoid InvalidCastException?
// NOTE: because TResult in our case - result type of the nested pipe
var result = await _direct.SendAsync<TResult /* replace with non generic SendAsync */>(getService, request!) !;
if (_nestedPipe is IPipelineAsync)
{
return await _nestedPipe.SendAsync<TResult>(getService, result!);
}
return result;
}
Am i on the right direction? Should i continue to work on it, not sure i'm competent enough..
Hey @qpippop!
You were narrow on what I'd like to see. To avoid the invalid cast, what if:
if (_nestedPipe is IPipelineAsync)
{
var result = await _direct.SendAsync<object>(getService, request!) !;
return await _nestedPipe.SendAsync<TResult>(getService, result!);
}
else
{
return await _nestedPipe.SendAsync<TResult>(getService, result!);
}
Would that work?
I am looking forward the PR. Hope we could merge it soon ☕️
It would be cool if the "Return" operator could start a second pipeline using the "Response" as the Request for the following pipeline.