API Reference ResultTransformationExtensions - ulfbou/Zentient.Results GitHub Wiki
Namespace:
Zentient.Results
Assembly:Zentient.Results.dll
Available since:v0.1.0
Provides extension methods for IResult
and IResult<T>
enabling functional transformations, fluent chaining, and conditional execution based on result success or failure.
This class enables ergonomic monadic composition (
Bind
,Then
) and projection (Map
) of result values, empowering developers to build failure-aware pipelines with minimal boilerplate.
These extensions are grounded in functional programming principles, designed to simplify conditional workflows without if
/else
branching or exceptions.
- β»οΈ Composable Control Flow: Enable functional chaining based on result state (
Bind
,Then
). - π― Selective Execution: Avoid unnecessary computations on failures.
- π§Ό Fluent Expression: Provide ergonomic syntax for value projection (
Map
) and action triggering. - π§ Generic Agility: Support chaining across both typed and untyped results (
IResult
,IResult<T>
). - π Null Safety: Guard all extension inputs with
ArgumentNullException
.
public static class ResultTransformationExtensions
-
Signature:
public static IResult<TOut> Map<TIn, TOut>(this IResult<TIn> result, Func<TIn, TOut> selector)
-
Summary: Projects the value of a successful result into a new value type.
-
Parameters:
-
result
(this IResult<TIn>
): Source result to transform. -
selector
(Func<TIn, TOut>
): Mapping function.
-
-
Return Value:
IResult<TOut>
with projected value or propagated failure. -
Behavior: Executes
selector
only if the result is successful. -
Exceptions Thrown:
ArgumentNullException
(if arguments are null). -
Example Usage:
var result = userResult.Map(u => u.Id);
-
Signature:
public static async Task<IResult<TOut>> Bind<TIn, TOut>(this IResult<TIn> result, Func<TIn, Task<IResult<TOut>>> next)
-
Summary: Asynchronously transforms the result using a next operation.
-
Return Value:
Task<IResult<TOut>>
-
Behavior: Executes
next
only if the result is successful. -
Example Usage:
var result = await userResult.Bind(u => userService.GetDetailsAsync(u.Id));
-
Signature:
public static async Task<IResult> Bind(this IResult result, Func<Task<IResult>> next)
-
Signature:
public static IResult Then<TIn>(this IResult<TIn> result, Func<TIn, IResult> func)
-
Summary: Applies a side-effectful operation on success without transforming the result type.
-
Example Usage:
var result = userResult.Then(u => audit.LogAccess(u));
-
Signature:
public static IResult Bind<TIn>(this IResult<TIn> result, Func<TIn, IResult> binder)
-
Signature:
public static IResult Bind(this IResult result, Func<IResult> binder)
-
Signature:
public static IResult<TOut> Bind<TOut>(this IResult result, Func<IResult<TOut>> binder)
-
Signature:
public static IResult<TOut> Then<TIn, TOut>(this IResult<TIn> result, Func<TIn, IResult<TOut>> func)
-
Signature:
public static IResult Then(this IResult result, Func<IResult> func)
-
Signature:
public static IResult<TOut> Then<TOut>(this IResult result, Func<IResult<TOut>> func)
var result = GetUser()
.Bind(user => Validate(user))
.Then(user => logger.LogInformation("User valid"))
.Map(user => user.Id);
var dataResult = await Authenticate()
.Bind(token => api.FetchAsync(token));
- All methods are pure in behavior and favor declarative chaining over imperative control flow.
- These methods do not mutate any result instanceβthey return new results.
- Use
Map
for projection andBind
for chaining monadic operations. -
Then
is ideal for executing effects like logging or analytics conditionally.
Layer / Module | Role |
---|---|
CQRS Pipelines |
For chaining handler logic. |
Zentient.Endpoints |
Intermediate adapters use Bind to short-circuit failures. |
Zentient.Results.Async |
Complemented with BindAsync , ThenAsync , and parallel tools. |
IResult
IResult<T>
Result
ResultTryExtensions
ResultValueExtractionExtensions
#API
#ExtensionMethods
#FunctionalComposition
#Bind
#Map
#ResultPattern
#ZentientCore
Last Updated: 2025-06-22 Version: 0.4.0