Modular .NET NuGet ecosystem that bridges OOP and Functional Programming in C#.
| Package | Description | Docs | NuGet |
|---|---|---|---|
CSharpEssentials |
Meta-package: Results + Errors + Maybe + Any + Core + Enums | 📖 | |
CSharpEssentials.Results |
Result<T> — railway-oriented error handling without exceptions |
📖 | |
CSharpEssentials.Errors |
Structured Error values with type, code, description, metadata |
📖 | |
CSharpEssentials.Maybe |
Maybe<T> — explicit optionals, no null reference exceptions |
📖 | |
CSharpEssentials.Any |
Any<T1,T2,...> — type-safe discriminated unions |
📖 | |
CSharpEssentials.Core |
String/GUID/collection utilities | 📖 | |
CSharpEssentials.Enums |
[StringEnum] source generator — AOT-safe enum↔string |
📖 | |
CSharpEssentials.Rules |
Composable rule engine with .And()/.Or()/.Linear()/.Next() |
📖 | |
CSharpEssentials.Mediator |
CQRS pipeline behaviors: validation, logging, caching, transactions | 📖 | |
CSharpEssentials.Entity |
EntityBase<TId>, soft deletion, domain events |
📖 | |
CSharpEssentials.EntityFrameworkCore |
EF Core interceptors (audit, events, slow queries) + pagination | 📖 | |
CSharpEssentials.AspNetCore |
GlobalExceptionHandler, ResultEndpointFilter, Swagger versioning |
📖 | |
CSharpEssentials.Http |
HttpClient extensions returning Result<T> |
📖 | |
CSharpEssentials.Json |
Pre-configured System.Text.Json options and converters |
📖 | |
CSharpEssentials.RequestResponseLogging |
Request/response body logging middleware | 📖 | |
CSharpEssentials.GcpSecretManager |
GCP Secret Manager → IConfiguration provider |
📖 | |
CSharpEssentials.Time |
Testable IDateTimeProvider wrapping TimeProvider |
📖 | |
CSharpEssentials.Validation |
High-performance model-first validation with Result<T> integration |
📖 | |
CSharpEssentials.Clone |
ICloneable<T> — typed deep-copy for entity collections |
📖 |
API Reference — Complete guide to every package, method, and pattern in the ecosystem. Covers all 19 packages with method tables, philosophy, code examples, and cross-cutting FP patterns.
# Core functional modules
dotnet add package CSharpEssentials
# Individual packages
dotnet add package CSharpEssentials.Rules
dotnet add package CSharpEssentials.MediatorStop throwing exceptions for expected failures. Chain operations that short-circuit on the first error.
// ❌ Traditional: exceptions as control flow
public User GetUser(Guid id)
{
var user = _db.Find(id);
if (user == null) throw new NotFoundException("User not found");
return user;
}
// ✅ Result<T>: explicit, composable error handling
public Result<User> GetUser(Guid id)
{
var user = _db.Find(id);
if (user is null) return Error.NotFound("User not found");
return Result.Success(user);
}
// Chain operations — stops at first failure, no try/catch needed
Result<UserDto> result = GetUser(id)
.Bind(user => ValidateAge(user))
.Bind(user => CheckPermissions(user))
.Map(user => new UserDto(user));Model the absence of a value without null references.
// ❌ Null checks everywhere, easy to miss
string display = user?.Profile?.DisplayName?.Trim()?.ToUpper() ?? "ANONYMOUS";
// ✅ Maybe<T>: pipeline that handles absence at every step
string display = Maybe.Return(user)
.Bind(u => Maybe.Return(u.Profile))
.Bind(p => Maybe.Return(p.DisplayName))
.Map(n => n.Trim().ToUpper())
.Fallback("ANONYMOUS");A value that is exactly one of several types — exhaustively matched at compile time.
Any<Circle, Rectangle, Triangle> shape = new Circle(radius: 5);
double area = shape.Match(
circle => Math.PI * circle.Radius * circle.Radius,
rectangle => rectangle.Width * rectangle.Height,
triangle => 0.5 * triangle.Base * triangle.Height
// compiler error if any case is missing
);Build complex validation logic from simple, reusable rules that return Result<T>.
var minAge = Rule.Create<User>(u => u.Age >= 18, Error.Validation("Must be 18+"));
var validEmail = Rule.Create<User>(u => u.Email.Contains('@'), Error.Validation("Invalid email"));
var verified = Rule.Create<User>(u => u.IsVerified, Error.Validation("Account not verified"));
// AND — all rules must pass, collects every failure
Result<User> result = RuleEngine
.Create(minAge, validEmail, verified)
.Evaluate(user);
// OR — at least one rule must pass
Result<User> adminOrMod = RuleEngine
.Create(isAdmin, isModerator)
.Or()
.Evaluate(user);Map Result<T> to correct HTTP status codes without writing any error-mapping boilerplate.
// Program.cs
app.AddCSharpEssentials(); // registers GlobalExceptionHandler + ProblemDetails
// Controller — business logic returns Result<T>, HTTP mapping is automatic
[HttpGet("{id:guid}")]
public IActionResult GetProduct(Guid id)
=> _productService.GetProduct(id).Match(
onSuccess: product => Ok(product),
onFailure: errors => errors.ToActionResult() // 404 / 400 / 409 based on ErrorType
);
// Service — chain multiple steps, first failure short-circuits
public Result<Order> PlaceOrder(Guid productId, int quantity)
=> _productService.GetProduct(productId)
.Then(p => ValidateStock(p, quantity))
.Then(p => ReserveStock(p, quantity))
.Then(p => CreateOrder(p, quantity));Install skills for Claude Code, Cursor, Codex, and 50+ other AI agents:
npx skills add senrecep/CSharpEssentialsEach package has a dedicated skill with accurate API examples, correct namespaces, and common pitfalls.