Implementation for the Operation Result Pattern.
$ dotnet add package RoyalCode.OperationResultThe OperationResult library is an essential component for handling the return of operations in systems developed in .Net. Designed to simplify the communication of success or failure between different parts of the system, such as: use cases, APIs, Controllers and HTTP requests, it offers a few main structs/classes, for different situations, called OperationResult, ValidableResult, ResultMessage and ResultErros, also, it supports conversion to ProblemDetails and has components for serialization and deserialization.
OperationResult is a struct that contains the result of an operation, or function, of a system. In case of failure the return will contain messages to inform the problem occurred. This is lighter than firing exceptions.OperationResult also has its own generic version, OperationResult<TValue>, allowing you to return results from different types of operations in your system consistently and efficiently.ValidableResult allows you to add error messages, allowing you to use them in validation scenarios.ResultMessage class.ResultMessage class allows you to associate meaningful error codes with the results of unsuccessful operations, making it easier to identify and deal with problems.ProblemDetails: The conversion of results into objects of type is facilitated by the library, allowing the standardization of error presentation according to the RFC 7807 specification.ProblemDetailsResultMessage class provides support for serialization and deserialization, making the exchange of information between different system components more practical and consistent.OperationResult from HTTP responses, deserilizing the messages and converting ProblemDetails, also supporting plain text.+= to add messages to the error collection and conversions between errors, message values and return types.OperationResult encapsulates the value or collection of errors depending on whether the result is success or failure. To work with these values, there are methods to extract or convert them.It is simple to start using the OperationResult library in your project:
Install the NuGet package: dotnet add package RoyalCode.OperationResult.
Import the namespace into your code:
using OperationResults;OperationResult<T> and returns an error message or the value.:public OperationResult<MyModel> DoSomething(string input)
{
if (string.IsNullOrEmpty(input))
return ResultMessage.InvalidParameter("Some error message", nameof(input));
return new MyModel(input);
}4 - You can also return an OperationResult in minimal APIs, using methods for converting to IResult:
// MapPost("/products")
public static async Task<CreatedMatch<Product>> Create(
ProductDto productDto /* FromBody */,
IProductService productService /* FromServices */)
{
OperationResult<Product> result = await productService.CreateProductAsync(productDto);
return result.CreatedMatch(p => $"products/{p.Id}");
}5 - There are implicit conversions for the 'Match' types in the library, such as the example for OkMatch<T>:
// MapGet("/products/{id}")
public static OkMatch<Product> Get(int id, IProductService productService)
{
Product? product = productService.Find(id);
if (product is null)
return ResultMessage.NotFound("Product not found", nameof(id));
return product;
}6 - You can also convert an HttpResponseMessage to an OperationResult:
var response = await client.GetAsync("api/products/1");
OperationResult<ProductDto> result = await response.ToOperationResultAsync<ProductDto>();See more details in the documentation.