OnRails 3.0.0
See the version list below for details.
dotnet add package OnRails --version 3.0.0
NuGet\Install-Package OnRails -Version 3.0.0
<PackageReference Include="OnRails" Version="3.0.0" />
<PackageVersion Include="OnRails" Version="3.0.0" />
<PackageReference Include="OnRails" />
paket add OnRails --version 3.0.0
#r "nuget: OnRails, 3.0.0"
#addin nuget:?package=OnRails&version=3.0.0
#tool nuget:?package=OnRails&version=3.0.0
OnRails
About
OnRails is a railway-oriented programming library for C#. It simplifies handling complex workflows by utilizing the principles of success and failure paths, making code easier to read, maintain, and extend.
Railway Oriented
The Railway Oriented Programming (ROP) pattern separates the pure functional domain logic from the side effects, by
representing them as a sequence of functions that return an Either type, representing either a successful Result
or an error. This allows for better composition and testing of functions, as well as improving the code's **
maintainability** and readability.
It also facilitates the handling of errors, as the error handling logic is separated from the main logic, making it easier to reason about and handle errors in a consistent and predictable manner. Overall, ROP can lead to more robust and reliable software systems.
Error Handling
In functional programming, it is not always appropriate to use traditional try-except
blocks because they can lead to
code that is difficult to read, understand, and maintain.
OnRails
supports functional error handling. The goal of this library is to make error handling more explicit,
composable, and testable. By using this library, developers can write code that is more robust, maintainable, and
expressive.
What problems are solved?
Railway Oriented Programming (ROP) solves several common problems in software development, such as:
Handling errors: By using an Either (
Result
) type, ROP makes it easy to represent and handle errors in a consistent and predictable manner, avoiding errors being thrown and allowing for error handling logic to be separated from the main logic.Composition: ROP separates the pure functional domain logic from the side effects, such as I/O, by representing them as a sequence of functions. This makes it easy to compose and chain functions together, enabling better code reuse and maintainability.
Readability: The separation of pure functional domain logic from the side effects makes the code more readable and understandable, as it makes it clear what each function does and how they relate to each other.
Testing: The pure functional domain logic can be easily tested, as it does not depend on any external state or side effects. This simplifies testing and ensures that the code is correct.
Overall, ROP provides a structured approach to software development that makes it easier to handle errors, compose functions, and test code, leading to more robust and reliable software systems.
Developers can spend less time debugging and more time writing code that adds value to their organization. Additionally, by using functional programming concepts, developers can write code that is easier to reason about and understand, which can lead to faster development cycles and better quality code.
Getting Started
Usage
Sample 1
using OnRails.Extensions.OnFail;
using OnRails.Extensions.OnSuccess;
using OnRails.Extensions.Try;
TryExtensions.Try(() => {
Console.Write("Enter a number: ");
var input = Console.ReadLine();
return Convert.ToInt32(input);
})
.OnSuccess(number => Console.WriteLine($"Number is valid: {number}"))
.OnFail(result => {
Console.WriteLine($"Is Success? {result.Success}"); // False
Console.WriteLine("Error Detail:");
Console.WriteLine(result.Detail?.ToString() ?? "No Data!");
return result;
});
Sample 2: Custom Error Detail
using OnRails;
using OnRails.Extensions.OnFail;
using OnRails.Extensions.OnSuccess;
using OnRails.ResultDetails.Errors.BadRequest;
DivideNumber(5, 0)
.OnSuccess(value => Console.WriteLine($"Result: {value}"))
.OnFailOperateWhen(result => result.Detail is DivideByZeroError,
result => {
Console.WriteLine($"Oops! We can not divide by zero! \n{result.Detail}");
return result;
});
static Result<double> DivideNumber(int a, int b) =>
b == 0
? Result<double>.Fail(new DivideByZeroError(nameof(b)))
: Result<double>.Ok(a * 1.0 / b);
// Define Custom ErrorDetail
public class DivideByZeroError(
string fieldName,
string fieldMessage = "Cannot divide by zero",
bool view = true) : ValidationError(fieldName, fieldMessage, view);
Extensions
ActionResult: Provides methods for working with ASP.NET Action Results, such as
ReturnAccepted
,ReturnCreated
, andResetContent
.Bind: Methods for binding data efficiently, e.g.,
BindExtensions
.Configuration: Extensions for configuration management, e.g.,
ConfigurationExtensions
.Fail: Handles failure conditions with methods like
FailWhen
.ForEach: Iteration helpers for both synchronous and asynchronous loops.
Must: Asserts conditions using
MustExtensions
.Object: General-purpose object manipulation methods.
OnFail / OnSuccess: Handles failure and success conditions, including adding or removing details, operations, and chaining methods.
OperateWhen: Facilitates conditional operations.
Tee / Using: Implements functional programming patterns like
Tee
and resource management withUsing
.
Result Details
- Errors:
- Structured error types like
BadRequestError
,ConflictError
,ValidationError
, andUnauthorizedError
. - Specialized internal errors (
ExceptionError
,InternalError
, etc.).
- Structured error types like
- Success:
- Success result types such as
AcceptedDetail
,CreatedDetail
,NoContentDetail
, and more.
- Success result types such as
- Warnings:
- Supports warning details via
WarningDetail
.
- Supports warning details via
CHANGELOG
Please see the CHANGELOG file.
Features
Rich Extensions: Offers a wide range of extension methods grouped by functionality for streamlined workflows.
Error Handling: Detailed error management with a structured hierarchy.
Customizable: Extensible design allowing users to add their own custom result details and extensions.
Integration Support: Built-in features for integrating with ASP.NET
Contributing
First off, thanks for taking the time to contribute! Contributions are what make the free/open-source community such an amazing place to learn, inspire, and create. Any contributions you make will benefit everybody else and are greatly appreciated.
Please read our contribution guidelines, and thank you for being involved!
Authors & contributors
The original setup of this repository is by Payadel.
For a full list of all authors and contributors, see the contributors page.
Security
OnRails follows good practices of security, but 100% security cannot be assured. OnRails is provided "as is" without any warranty.
For more information and to report security issues, please refer to our security documentation.
License
This project is licensed under the GPLv3.
See LICENSE for more information.
Related
Here are some related projects
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.