Documentation
A .NET helper library that standardizes process and data outputs, provides a paginated output container, and includes IQueryable pagination extension methods (synchronous & asynchronous).
Contents
- Project overview
- Classes
ProcessOutputDataOutputPaginatedOutputCustomExceptionPaginatedOutputExtensions(extension methods)
- Usage examples
- Add as a Git submodule and reference
- Mermaid class diagram
- Notes
Overview
ArturRios.Output provides lightweight types to represent the result of operations in a consistent way. Typical use
cases:
- Return success/failure information together with messages and errors
- Return typed data payloads with fluent helpers
- Return paginated list results and help paginate
IQueryablesources (works with EF Core or in-memory LINQ)
The library has no external runtime dependencies apart from Microsoft.EntityFrameworkCore when you call the EF-aware
PaginateAsync extension (the extension is written to work with both IQueryables that support async and ones that
don’t).
Classes
ProcessOutput- Purpose: Base container for operation results. Captures messages, errors, timestamp and a convenience
Successflag. - Key members:
List<string> Messages { get; }List<string> Errors { get; }DateTime Timestamp { get; }(UTC)bool Success { get; }(true when no errors)- Fluent helpers:
WithError,WithErrors,WithMessage,WithMessages - Add helpers:
AddError,AddErrors,AddMessage,AddMessages - Static factory:
ProcessOutput.New
- Purpose: Base container for operation results. Captures messages, errors, timestamp and a convenience
DataOutput<T>:ProcessOutput- Purpose: Holds a typed data payload plus everything
ProcessOutputprovides. - Key members:
T? Data { get; protected set; }- Fluent API:
WithData(T),WithError(string),WithErrors(IEnumerable<string>),WithMessage(string),WithMessages(IEnumerable<string>) - Static factory:
DataOutput<T>.New
- Purpose: Holds a typed data payload plus everything
PaginatedOutput<T>:DataOutput<List<T>>- Purpose: Represents a paginated result set containing
List<T>as the payload. - Key members:
int PageNumber { get; set; }int PageSize { get; }(derived from Data?.Count)int TotalItems { get; set; }int TotalPages { get; }(computed as Ceil(TotalItems / PageSize))- Helpers to build:
WithPagination(int pageNumber, int totalItems),WithData(List<T>),WithData(T),WithEmptyData(),AddItem(T),AddItems(IEnumerable<T>) - Fluent
WithMessage/WithErroroverloads preserved. - Static factory:
PaginatedOutput<T>.New
- Purpose: Represents a paginated result set containing
CustomException(abstract)- Purpose: Base exception type wrapping an array of messages. Derive from it to create domain-specific exceptions that carry multiple messages.
- Key members:
- Constructor that accepts
string[] messagesand builds the baseExceptionmessage by joining them string[] Messages { get; }
- Constructor that accepts
PaginatedOutputExtensions(static)- Purpose: Extension methods for
IQueryable<T>to paginate a query and return aPaginatedOutput<T>. - Methods:
Task<PaginatedOutput<T>> PaginateAsync<T>(this IQueryable<T> query, int pageNumber, int pageSize, Expression<Func<T, object?>>? orderBy = null, CancellationToken cancellationToken = default)- Uses EF Core async if the query provider supports
IAsyncQueryProvider; otherwise falls back to synchronousToList().
- Uses EF Core async if the query provider supports
PaginatedOutput<T> Paginate<T>(this IQueryable<T> query, int pageNumber, int pageSize, Expression<Func<T, object?>>? orderBy = null)- Synchronous variant. When provided,
orderByis applied.
- Synchronous variant. When provided,
- Purpose: Extension methods for
Usage examples
Basic (ProcessOutput / DataOutput)
using ArturRios.Output;
// Simple success response with a message
var p = ProcessOutput.New.WithMessage("Operation completed");
// Data output
var d = DataOutput<int>.New
.WithData(42)
.WithMessage("Value computed");
if (!d.Success) {
// inspect d.Errors
}
Paginated example (synchronous)
using ArturRios.Output;
IQueryable<MyEntity> query = ...; // your LINQ or EF Core query
int pageNumber = 1;
int pageSize = 20;
var page = query.Paginate(pageNumber, pageSize, e => e.CreatedAt);
// page is PaginatedOutput<MyEntity>
var items = page.Data; // List<MyEntity>
Paginated example (async, EF Core)
using ArturRios.Output;
var page = await dbContext.Set<MyEntity>()
.Where(e => e.IsActive)
.PaginateAsync(pageNumber: 2, pageSize: 50, orderBy: e => e.CreatedAt, cancellationToken: ct);
var items = page.Data; // List<MyEntity>
How to use in your project
Add as a Git submodule and reference the project in your solution:
# from your solution repository root
git submodule add <git-url-of-this-repo> external/dotnet-output
git submodule update --init --recursive
# then add the csproj to your solution (adjust path)
dotnet sln add external/dotnet-output/src/ArturRios.Output.csproj
This keeps the library as a normal project dependency and allows debugging into its code.
API notes & gotchas
PaginatedOutput.PageSizeis derived from the returnedData.Count(i.e., the number of items in the current page).TotalItemsis intended to be the total number of items across all pages.TotalPagesis computed asCeiling(TotalItems / PageSize).
Class diagram
Below is a mermaid class diagram representing the public classes in this project. You can paste this into any mermaid-enabled renderer (for example GitHub markdown with mermaid enabled, or live editors).
classDiagram
class ProcessOutput {
+Messages: List_string
+Errors: List_string
+Timestamp: DateTime
+Success: bool
}
class DataOutput_T {
+Data: T_optional
}
class PaginatedOutput_T {
+PageNumber: int
+PageSize: int
+TotalItems: int
+TotalPages: int
}
class CustomException {
+Messages: string_array
}
class PaginatedOutputExtensions {
+PaginateAsync()
+Paginate()
}
DataOutput_T --|> ProcessOutput
PaginatedOutput_T --|> DataOutput_T
PaginatedOutputExtensions ..> PaginatedOutput_T: uses
Contributing
Contributions are welcome. For small fixes a PR with tests and a few usage examples is ideal.