Issue with Generic Wrapper as response type in pipeline
See original GitHub issueWhen adding a Generic request result wrapper to all of my mediator request response types, the pipeline refuses to execute, throwing a generic type constraint exception that the request does not fit the type constraint of TRequest, which is
where TRequest : IRequest<RequestResponse<TResponse>>
The request sent is of type
IRequest<RequestResponse<Detail>>
The exact exception is
Message "GenericArguments[0], 'Api.MediatR.Requests.GetDetailsRequest', on 'Api.MediatR.Behaviours.ExceptionHandlingBehaviour2[TRequest,TResponse]' violates the constraint of type parameter 'TRequest'." string
The full class in question is
public class ExceptionHandlingBehaviour<TRequest, TResponse> :
IPipelineBehavior<TRequest,RequestResponse<TResponse>>
where TRequest : IRequest<RequestResponse<TResponse>>
{
public async Task<RequestResponse<TResponse>> Handle(TRequest request, RequestHandlerDelegate<RequestResponse<TResponse>> next)
{
try
{
return await next();
}
catch (Exception ex)
{
return new RequestResponse<TResponse>(ex);
}
}
}
With RequestResult being
public class RequestResponse<TResponse>
{
public RequestResponse(RequestState reason, string message = null)
{
RequestState = reason;
Failure = message != null ? new Exception(message) : new Exception(reason.ToString());
}
public RequestResponse(List<ValidationFailure> validationFailures)
{
ValidationFailures = validationFailures;
RequestState = RequestState.ValidationFailure;
}
public RequestResponse(TResponse response)
{
RequestState = RequestState.Success;
Response = response;
}
public RequestResponse(Exception exception)
{
Failure = exception;
RequestState = RequestState.Error;
}
public readonly TResponse Response;
public readonly IEnumerable<ValidationFailure> ValidationFailures;
public readonly Exception Failure;
public RequestState RequestState;
}
Is this just me stuffing up generics, or is something not working correctly here?
Issue Analytics
- State:
- Created 6 years ago
- Comments:6 (3 by maintainers)
Top Results From Across the Web
Constraint Violated Exception on MediatR Behavior
This means that in your generic implementation, TRequest will be Request , and TResponse will be Envelope<Response> . This however means that ...
Read more >How to wrap a route not found exception with the generic ...
I am trying to capture the exception when the route is not found and wrap the exception with the generic response model.
Read more >Creating generic networking APIs in Swift
One option would be to wrap the model that we're looking to extract into a dedicated response type that we can then decode...
Read more >Understanding TypeScript Generics
An introduction to the utilization of Generics in TypeScript with examples grounded in real-world use cases, such as collections, ...
Read more >MediatR Pipeline Examples
My authorization handler applies the former based on generic type (TRequest, TResponse) and the latter based on an attribute I add to my...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@stumpykilo let me know if this is what you are looking for.
This is close to what we do in our project.
@jakerabjohns15 check out these lines
what you are saying here is that
ExceptionHandlingBehaviour
is a generic class that accepts two types,TRequest
andTResponse
.This class also implements a Generic interface that accepts two generic types
TRequest
(which is the same as the generic fromExceptionHandlingBehaviour
andRequestResponse<TResponse>
. HereTResponse
is also carried over fromExceptionHandlingBehaviour
. Are you seeing the problem?If
TRequest
is constrained to types ofIRequest<RequestResponse<TResponse>>
that means thatTResponse
is intended through mediatr’s rules to be of typeRequestResponse<TResponse>
.This would imply that
TResponse
itself is of typeRequestResponse<TResponse>
which would imply that the pipeline to be limited toIPipelineBehavior<TRequest, RequestResponse<RequestResponse<TResponse>>>
. You can see how this might be a problem.To do what you need you cannot reference the
TResponse
twice. You will need to encapsulate theException
part into a parent class.And then modify your pipeline handler like so:
This should give you the desired behavior