ModResults provides a structured way to represent success or failure with optional details, enhancing readability and maintainability in codebases. It is designed for both in-process and networked scenarios with serialization/deserialization support. The library leverages nullability annotations, immutability, and factory methods for clarity.
- Result Pattern: Encapsulates success or failure states with associated error messages and additional information.
- Ready-to-Use Implementations:
Result
andResult<TValue>
with a defaultFailure
state.Result<TValue, TFailure>
for custom failure states.
- 📦 Extension Packages for Various Scenarios:
ModResults.FluentValidation
bridges FluentValidation with ModResults for unified validation error handling.ModResults.MinimalApis
provides extensions to convert Result and Result<TValue> instances to ASP.NET Core Minimal APIs' IResult responses with proper HTTP status codes and response formatting.ModResults.Orleans
provides surrogate and converter implementations required by the Orleans serializer.
- Serialization: JSON serialization/deserialization without special configuration.
- Success: Use
Result.Ok()
orResult<TValue>.Ok(TValue value)
. - Failure: Use static methods like
Result.NotFound()
orResult<TValue>.NotFound()
.
public async Task<Result<GetBookByIdResponse>> GetBookById(GetBookByIdRequest req, CancellationToken ct)
{
var entity = await db.Books.FirstOrDefaultAsync(b => b.Id == req.Id, ct);
return entity is null ?
Result<GetBookByIdResponse>.NotFound() :
Result.Ok(new GetBookByIdResponse(
Id: entity.Id,
Title: entity.Title,
Author: entity.Author,
Price: entity.Price));
}
A result can either be in an Ok or Failed state.
- Ok State: The
Result<TValue>
instance contains a non-nullValue
of typeTValue
. - Failed State: Both
Result
andResult<TValue>
instances contain a non-nullFailure
of typeFailure
.
public async Task<Result> PerformGetBookById(GetBookByIdRequest req, CancellationToken ct)
{
var result = await GetBookById(req, ct);
if (result.IsOk)
{
Console.WriteLine($"GetBookById is successful. Book title is {result.Value.Title}");
}
else
{
Console.WriteLine($"GetBookById has failed.");
}
return result
}
For more advanced examples, refer to the following:
- Adding Information to Results
- Create a Failed Result from Exceptions
- Converting a Result to Another Result
- Mapping Results into Other Objects
- Minimal API Integration: If you're utilizing Minimal APIs and need to map a
Result
orResult<TValue>
to an API response, consider exploring theWebServiceEndpoint
implementation in the ModEndpoints project. This project organizes ASP.NET Core Minimal APIs into REPR format endpoints and seamlessly integrates with the result pattern, including automatic response mapping. - Microsoft Orleans Integration: Include ModResults.Orleans package as project dependency to use Result and Result<TValue> objects in Orleans grains.