Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/deshansl/returns
Result pattern support nuget package.
https://github.com/deshansl/returns
csharp dotnet dotnet-core dotnetnugetutil nuget nuget-package result result-pattern resultpattern return returns simple
Last synced: 22 days ago
JSON representation
Result pattern support nuget package.
- Host: GitHub
- URL: https://github.com/deshansl/returns
- Owner: DeshanSL
- Created: 2024-06-19T00:21:59.000Z (5 months ago)
- Default Branch: master
- Last Pushed: 2024-10-01T03:04:49.000Z (about 1 month ago)
- Last Synced: 2024-10-01T11:12:18.790Z (about 1 month ago)
- Topics: csharp, dotnet, dotnet-core, dotnetnugetutil, nuget, nuget-package, result, result-pattern, resultpattern, return, returns, simple
- Language: C#
- Homepage:
- Size: 49.8 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: Readme.md
Awesome Lists containing this project
README
### Simplify error handling and improve code readability with the Result Pattern
## Get Started
#### Install nuget package using .Net CLI
or nuget using Nuget package manager GUI by searching DeepCode.Return
```bash
dotnet add package DeepCode.Return --version 1.0.1
```## How To Use
#### Define method return type with Return struct with TResult type parameter
TResult is type of the return
```csharp
namespace Invoicing.Application.Orders.Commands.CreateOrderCommand;internal class CreateOrderCommandHandler : IRequestHandler>
{
public async Task> Handle(CreateOrderCommand request, CancellationToken cancellationToken)
{
Order order;
//order creation logic
return order;
}
}
```for non async methods
```csharp
public Return CreateOrder(CreateOrder request, CancellationToken cancellationToken)
{
Order order;//order creation logic
return order;
}
```#### Return struct can be used when there's no return value but to notify if function was success or not
```csharp
public Return SendEmail()
{
return Return.Success();
}
```### How to extract if state is success
```csharp
Return orderCreateResult = CreateOrder(request, cancellationToken);
if(orderCreateResult.IsFailure)
{
// Failure code goes here
}
Order order = orderCreateResult.Value;
// success path here```
### Error Handling
#### Notify caller error with in built error types
Handle Conflicts,
```csharp
public Return CreateOrder(double totalAmount)
{
// logic to apply the discount if total amount is > 100
// Inventory says out of stock due to high demandif (!inventoryManagement.AreEnoughStokesAvailable())
{
return Fault.Conflict("Not enough stockes in inventory.");
//or
return Return.Failure(Conflict.Create("Not enough stockes in inventory."));
}}
```#### Other in-built error type available
```csharp
// all these take one string message arg and optinal description arg
return Fault.NotFound();
return Fault.InternalError();
return Fault.ReturnError();
```#### Type check errors for decision making
```csharp
Return result = GetOrder(id);
if(result.IsFailure)
{if(result.IsErrorTypeOf())
{
// Not found logic goes here.
}if(result.ErrorsContain())
{
// if error list contains Not found logic goes here.
}if(result.Error.Is())
{
// Unauthorize logic goes here.
}if(result.Errors.ContainsErrorType())
{
// Not found logic goes here.
}if(result.Errors.ContainsErrorType())
{
// if custom error type
}}
```
#### Handle Errors from caller method
```csharp
Return orderCreateResult = CreateOrder(100);
if (orderCreateResult.IsFailure)
{
// First error or only error of the list.
Fault error = orderCreateResult.Error;// Read all errors returned.
IReadOnlyList errors = orderCreateResult.Errors;// Error logic goes here
}if (orderCreateResult.IsFailure)
{
// Pass errors to call stack
return orderCreateResult.Errors.ToList();
}
```#### Define custom error types
Need to be inherited from Fault record
```csharp
public record OrderCreationErrors : Fault
{
public OrderCreationErrors(string message, string? description = null) : base(message, description) { }public static OrderCreationErrors InvalidCustomerIdForOrderCreation =>
new OrderCreationErrors("Could not find matching customer to the given customerId.");public static OrderCreationErrors CustomerBlacklisted =>
new OrderCreationErrors("Customer with the given customerId has been blacklisted.");
}
```#### Using Match
Match method can be used to trigger actions when some return is success or failure.
Trigger actions with no return type.
```csharp
Return orderCreateResult = CreateOrder(100);orderCreateResult.Match(
onSuccess: (value) => _logger.Info($"{value.Id} Order created successfully."),
onFailure: (errors) => _logger.Error("Failed to create order.")
);//Match first error of errors if failure.
orderCreateResult.MatchFirst(
onSuccess: (value) => _logger.Info($"{value.Id} Order created successfully."),
onFailure: (error) => _logger.Error("Failed to create order.")
);orderCreateResult.MatchAsync(
onSuccess: async (value) =>
{
// Simulating async process
await Task.Delay(100);
_logger.Info($"{value.Id} Order created successfully.");
},
onFailure: async (errors) =>
{
// Simulating async process
await Task.Delay(100);
_logger.Error("Failed to create order.");
});```
Match using TNextValue type, has return after match
```csharp
Return orderCreateResult = Return.Success(new Order());Response response = orderCreateResult.Match>(
onSuccess:(order) => new Response() { Data = order },
onFailure:(errors) => new Response() { Error = new { Error = errors.ToList() } });//gets first error of the list as the arg when failure.
Response response = orderCreateResult.MatchFirst>(
onSuccess:(order) => new Response() { Data = order },
onFailure:(error) => new Response() { Error = new { Error = errors.ToList() } });Response response = orderCreateResult.MatchAsync>(
onSuccess: async (order) => {},
onFailure: async (errors) => {});//gets first error of the list as the arg when failure.
Response response = orderCreateResult.MatchFirstAsync>(
onSuccess: async (order) => {},
onFailure: async (error) => {});
```