Last active
June 5, 2018 11:27
-
-
Save joacar/827dc313b7ff5b6ede7d804b49640aec to your computer and use it in GitHub Desktop.
Operation MediatR pipeline
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using MediatR; | |
namespace TestingMediatR | |
{ | |
/// <summary> | |
/// Encapsulates the result of an request operation. | |
/// </summary> | |
public class OperationResult | |
{ | |
protected List<OperationMessage> _messages = new List<OperationMessage>(); | |
/// <summary> | |
/// List of <see cref="OperationMessage" />s. | |
/// </summary> | |
public IReadOnlyList<OperationMessage> Messages => _messages; | |
/// <summary> | |
/// The result of the operation. | |
/// </summary> | |
/// <value> | |
/// <c>true</c> if the operation succeeded, otherwise <c>false</c>. | |
/// </value> | |
public bool Succeeded { get; protected set; } | |
/// <summary> | |
/// Unhandled failure. | |
/// </summary> | |
/// <value> | |
/// The <see cref="Exception" /> thrown when the request was processed. | |
/// </value> | |
public Exception Failure { get; protected set; } | |
public static OperationResult Success { get; } = new OperationResult | |
{ | |
Succeeded = true | |
}; | |
public static OperationResult Failed(Exception exception) | |
{ | |
return new OperationResult | |
{ | |
Succeeded = false, | |
Failure = exception | |
}; | |
} | |
public static OperationResult Failed(params OperationMessage[] messages) | |
{ | |
var result = new OperationResult | |
{ | |
Succeeded = false | |
}; | |
if (messages != null) | |
{ | |
result._messages.AddRange(messages); | |
} | |
return result; | |
} | |
public static implicit operator bool(OperationResult result) | |
{ | |
return result.Succeeded; | |
} | |
public override string ToString() | |
{ | |
if (Succeeded) | |
{ | |
return "Succeeded"; | |
} | |
var message = Failure != null ? Failure.Message : string.Join(",", _messages.Select(_ => _.Code).ToArray()); | |
return $"Failed: {message}"; | |
} | |
} | |
/// <summary> | |
/// </summary> | |
/// <typeparam name="TResponse"></typeparam> | |
public class OperationResult<TResponse> : OperationResult | |
{ | |
public TResponse Response { get; set; } | |
public static implicit operator TResponse(OperationResult<TResponse> result) | |
{ | |
return result.Response; | |
} | |
public new static OperationResult<TResponse> Success(TResponse data) | |
{ | |
return new OperationResult<TResponse> | |
{ | |
Succeeded = true, | |
Response = data | |
}; | |
} | |
public new static OperationResult<TResponse> Failed(Exception exception) | |
{ | |
return new OperationResult<TResponse> | |
{ | |
Succeeded = false, | |
Failure = exception | |
}; | |
} | |
public new static OperationResult<TResponse> Failed(params OperationMessage[] messages) | |
{ | |
var result = new OperationResult<TResponse> | |
{ | |
Succeeded = false | |
}; | |
if (messages != null) | |
{ | |
result._messages.AddRange(messages); | |
} | |
return result; | |
} | |
} | |
public abstract class RequestResultWrapper<TRequest> : IRequestHandler<TRequest, OperationResult> | |
where TRequest : IOperationCommand | |
{ | |
public async Task<OperationResult> Handle(TRequest request, CancellationToken cancellationToken) | |
{ | |
try | |
{ | |
await HandleCore(request, cancellationToken).ConfigureAwait(false); | |
return OperationResult.Success; | |
} | |
catch (Exception exception) | |
{ | |
return OperationResult.Failed(exception); | |
} | |
} | |
public abstract Task HandleCore(TRequest request, CancellationToken cancellationToken); | |
} | |
public abstract class | |
RequestResultWrapper<TRequest, TResponse> : IRequestHandler<TRequest, OperationResult<TResponse>> | |
where TRequest : IOperationCommand<TResponse> | |
{ | |
public async Task<OperationResult<TResponse>> Handle(TRequest request, CancellationToken cancellationToken) | |
{ | |
try | |
{ | |
var response = await HandleCore(request, cancellationToken).ConfigureAwait(false); | |
return OperationResult<TResponse>.Success(response); | |
} | |
catch (Exception exception) | |
{ | |
return OperationResult<TResponse>.Failed(exception); | |
} | |
} | |
public abstract Task<TResponse> HandleCore(TRequest request, CancellationToken cancellationToken); | |
} | |
/// <summary> | |
/// Encapsulate details about any messages during the request operation. | |
/// </summary> | |
public class OperationMessage | |
{ | |
/// <summary> | |
/// Gets or sets the code for this message. | |
/// </summary> | |
/// <value> | |
/// The code for this message. | |
/// </value> | |
/// <remarks> | |
/// This value should be unique accross the domain. | |
/// </remarks> | |
public string Code { get; set; } | |
/// <summary> | |
/// Gets or sets the description for this message. | |
/// </summary> | |
/// <value> | |
/// The description for this message. | |
/// </value> | |
public string Description { get; set; } | |
} | |
/// <summary> | |
/// Marker interface for performing an operation without a specific result. | |
/// </summary> | |
public interface IOperationCommand : IRequest<OperationResult> | |
{ | |
} | |
/// <summary> | |
/// Marker interface for performing an operation expectng to return <typeparamref name="TResult" />. | |
/// </summary> | |
/// <typeparam name="TResult">Type of expected result.</typeparam> | |
public interface IOperationCommand<TResult> : IRequest<OperationResult<TResult>> | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment