MonadicSharp 1.3.3
dotnet add package MonadicSharp --version 1.3.3
NuGet\Install-Package MonadicSharp -Version 1.3.3
<PackageReference Include="MonadicSharp" Version="1.3.3" />
<PackageVersion Include="MonadicSharp" Version="1.3.3" />
<PackageReference Include="MonadicSharp" />
paket add MonadicSharp --version 1.3.3
#r "nuget: MonadicSharp, 1.3.3"
#addin nuget:?package=MonadicSharp&version=1.3.3
#tool nuget:?package=MonadicSharp&version=1.3.3
MonadicSharp 🚀
🏆 Created by Danny4897 (aka Klexir on NuGet) | 📦 Available on NuGet.org
A professional-grade functional programming library for C# featuring Result<T>, Option<T>, Railway-Oriented Programming, and advanced monadic patterns. Build enterprise-ready applications with bulletproof error handling and sophisticated control flow.
✨ Key Features
- 🚦 Result<T> - Advanced railway-oriented programming with comprehensive error handling
- 🎯 Option<T> - Null-safe operations and robust optional value management
- 🛡️ Try<T> - Sophisticated exception handling with retry mechanisms and circuit breakers
- ⚖️ Either<TLeft, TRight> - Elegant dual-state modeling for complex scenarios
- � Ensure<T> - Contract-based validation with fluent assertion patterns
- �🔄 Fluent Pipelines - Chain operations with elegant, readable syntax
- ⚡ Async Support - Complete async/await compatibility throughout
- 🏗️ Type Safety - Leverage C#'s advanced type system for bulletproof code
- 📦 Zero Dependencies - Lightweight, self-contained, and production-ready
- 🔐 Enterprise Protection - Advanced intellectual property protection measures
🏛️ Professional Architecture
MonadicSharp follows a clean, modular architecture:
MonadicSharp/
├── Core/ # Core monadic types
│ ├── Result.cs # Railway-oriented programming
│ ├── Option.cs # Null-safe operations
│ ├── Try.cs # Exception handling
│ ├── Either.cs # Dual-state modeling
│ ├── Ensure.cs # Contract validation
│ └── Unit.cs # Functional unit type
├── Extensions/ # Extension methods
│ ├── FunctionalExtensions.cs
│ ├── PipelineExtensions.cs
│ └── DbSetExtensions.cs
└── Documentation/ # Comprehensive docs
├── ATTRIBUTION.md
└── INTEGRITY.md
🚀 Quick Start
Installation
dotnet add package MonadicSharp
Essential Usage Patterns
🚦 Result<T> - Railway-Oriented Programming
using MonadicSharp.Core;
using MonadicSharp.Extensions;
// Chain operations with automatic error propagation
var result = Result.Success(42)
.Map(x => x * 2)
.Bind(x => x > 50 ? Result.Success(x) : Result.Failure("Value too small"))
.Map(x => $"Final value: {x}");
result.Match(
onSuccess: value => Console.WriteLine(value),
onFailure: error => Console.WriteLine($"Error: {error}")
);
🎯 Option<T> - Null-Safe Operations
var safeResult = GetUser()
.Map(u => u.Email)
.Filter(email => email.Contains("@"))
.GetValueOrDefault("no-email@example.com");
🛡️ Try<T> - Advanced Exception Handling
var robustOperation = Try.Execute(() => RiskyOperation())
.ExecuteWithRetry(maxAttempts: 3, delayMs: 1000)
.ExecuteWithCircuitBreaker(failureThreshold: 5, timeoutMs: 30000)
.Match(
onSuccess: result => $"Success: {result}",
onFailure: ex => $"Failed after all attempts: {ex.Message}"
);
⚖️ Either<TLeft, TRight> - Dual-State Modeling
Either<ValidationError, User> processUser = ValidateUser(userData)
.Match(
left: error => Either.Left<ValidationError, User>(error),
right: validData => Either.Right<ValidationError, User>(CreateUser(validData))
);
🔒 Ensure<T> - Contract Validation
var validatedUser = Ensure.That(user)
.IsNotNull("User cannot be null")
.Satisfies(u => u.Age >= 18, "User must be an adult")
.Satisfies(u => !string.IsNullOrEmpty(u.Email), "Email is required")
.Value; // Throws if any condition fails
🏗️ Project Templates
Get started quickly with MonadicSharp using our pre-built project templates:
Installation
# Install MonadicSharp templates
dotnet new install MonadicSharp.Templates
Available Templates
🚀 Monadic API (monadic-api
)
A lightweight REST API template with functional programming patterns:
dotnet new monadic-api -n MyApi
cd MyApi
dotnet run
🏛️ Monadic Clean Architecture (monadic-clean
)
A comprehensive Clean Architecture template with CQRS and functional patterns:
dotnet new monadic-clean -n MyApp
cd MyApp
dotnet run
Both templates include:
- ✅ Complete MonadicSharp integration
- ✅ Railway-Oriented Programming patterns
- ✅ Result<T> error handling
- ✅ Ready-to-run examples
- ✅ Best practices implementation
📖 Learn more: Check the Templates README for detailed documentation
🔧 Core Types & Advanced Patterns
Result<T> - Railway-Oriented Programming
The foundation of error handling without exceptions:
// Success and failure creation
var success = Result.Success("Hello World");
var failure = Result.Failure<string>("Something went wrong");
// Advanced chaining with validation
var result = GetUser(id)
.Bind(ValidateUser)
.Bind(EnrichUserData)
.Bind(SaveUser)
.Map(u => new UserDto(u.Id, u.Name));
// Comprehensive error handling
result.Match(
onSuccess: dto => ProcessSuccess(dto),
onFailure: error => LogAndHandle(error)
);
Option<T> - Sophisticated Null Safety
Beyond simple null checks - comprehensive optional value handling:
// Safe value creation
var some = Option.Some(42);
var none = Option.None<int>();
// Complex transformation chains
var result = GetUser()
.Map(u => u.Profile)
.Bind(p => p.GetPreference("theme"))
.Filter(theme => IsValidTheme(theme))
.Map(theme => ApplyTheme(theme))
.GetValueOrDefault(DefaultTheme);
Try<T> - Enterprise Exception Handling
Professional-grade exception management with advanced patterns:
// Basic exception handling
var result = Try.Execute(() => RiskyDatabaseOperation());
// Advanced retry with exponential backoff
var resilientResult = Try.Execute(() => CallExternalService())
.ExecuteWithRetry(
maxAttempts: 5,
delayMs: 1000,
backoffMultiplier: 2.0
);
// Circuit breaker pattern
var protectedResult = Try.Execute(() => UnreliableService())
.ExecuteWithCircuitBreaker(
failureThreshold: 10,
timeoutMs: 60000
);
// Composite operations with contextual error handling
var complexResult = Try.ExecuteCompositeOperation(
() => ValidateInput(),
() => ProcessData(),
() => SaveResults()
).ExecuteWithContextualErrorHandling("User registration process");
Either<TLeft, TRight> - Elegant Dual-State Modeling
Perfect for representing success/failure or valid/invalid states:
// Validation scenarios
Either<ValidationErrors, ValidUser> ValidateUser(UserInput input)
{
var errors = new List<string>();
if (string.IsNullOrEmpty(input.Email))
errors.Add("Email required");
if (input.Age < 18)
errors.Add("Must be adult");
return errors.Any()
? Either.Left<ValidationErrors, ValidUser>(new ValidationErrors(errors))
: Either.Right<ValidationErrors, ValidUser>(new ValidUser(input));
}
// Pattern matching
var processResult = ValidateUser(userInput)
.Match(
left: errors => HandleValidationErrors(errors),
right: validUser => ProcessValidUser(validUser)
);
Ensure<T> - Contract-Based Validation
Declarative validation with fluent syntax:
// Method parameter validation
public User CreateUser(string name, int age, string email)
{
Ensure.That(name).IsNotNullOrEmpty("Name is required");
Ensure.That(age).IsGreaterThan(0, "Age must be positive");
Ensure.That(email).Satisfies(e => e.Contains("@"), "Invalid email format");
return new User(name, age, email);
}
// Complex object validation
var validatedOrder = Ensure.That(order)
.IsNotNull("Order cannot be null")
.Satisfies(o => o.Items.Any(), "Order must have items")
.Satisfies(o => o.Total > 0, "Order total must be positive")
.Satisfies(o => o.Customer != null, "Order must have customer")
.Value;
// Chaining validations
var processedUser = Ensure.That(user)
.IsNotNull()
.Satisfies(u => u.IsActive, "User must be active")
.Transform(u => u.NormalizeEmail())
.Satisfies(u => u.HasValidSubscription(), "Valid subscription required")
.Value;
🔄 Advanced Pipeline Composition
Build sophisticated data processing pipelines with enterprise-grade error handling:
// Complex business logic pipeline
var userRegistrationPipeline = Pipeline
.Start<UserRegistrationRequest>()
.Then(ValidateUserInput)
.Then(CheckUserUniqueness)
.Then(HashPassword)
.Then(CreateUserEntity)
.Then(SaveUserToDatabase)
.Then(SendWelcomeEmail)
.Then(GenerateUserToken);
var result = await userRegistrationPipeline.ExecuteAsync(registrationRequest);
// Data transformation pipeline with error accumulation
var dataProcessingPipeline = Pipeline
.Start<RawDataInput>()
.Then(ValidateDataFormat)
.Then(NormalizeData)
.Then(EnrichWithMetadata)
.Then(ApplyBusinessRules)
.Then(TransformToOutputFormat)
.ThenAsync(SaveToStorage);
// Parallel processing with error collection
var batchProcessingResult = await Pipeline
.StartBatch(dataItems)
.ProcessInParallel(item => ProcessSingleItem(item))
.CollectResults()
.HandleErrors(errors => LogBatchErrors(errors));
🎯 Enterprise Error Handling Patterns
Traditional Approach (Problematic ❌)
public User GetUser(int id)
{
var user = database.Find(id);
if (user == null)
throw new UserNotFoundException();
if (!user.IsActive)
throw new UserInactiveException();
return user;
}
MonadicSharp Approach (Professional ✅)
public Result<User> GetUser(int id)
{
return Ensure.That(id).IsGreaterThan(0, "Invalid user ID")
.Transform(_ => database.Find(id))
.ToResult("User not found")
.Bind(ValidateUserActive)
.Bind(EnrichUserData);
}
private Result<User> ValidateUserActive(User user)
{
return user.IsActive
? Result.Success(user)
: Result.Failure("User account is deactivated");
}
private Result<User> EnrichUserData(User user)
{
return Try.Execute(() => userService.LoadUserProfile(user))
.ToResult("Failed to load user profile")
.Map(profile => user.WithProfile(profile));
}
Advanced Error Handling with Context
public async Task<Result<ProcessingResult>> ProcessComplexWorkflow(WorkflowRequest request)
{
return await Result.Success(request)
.Bind(ValidateWorkflowRequest)
.BindAsync(async req => await ExecuteWorkflowSteps(req))
.Bind(ValidateWorkflowResults)
.MapAsync(async results => await FinalizeWorkflow(results))
.Match(
onSuccess: result =>
{
logger.LogInformation("Workflow completed successfully: {WorkflowId}", result.Id);
return Result.Success(result);
},
onFailure: error =>
{
logger.LogError("Workflow failed: {Error}", error);
return Result.Failure<ProcessingResult>($"Workflow processing failed: {error}");
}
);
}
📖 Comprehensive API Reference
Result<T> Methods
Success<T>(T value)
- Create a successful resultFailure<T>(string error)
- Create a failed resultMap<TResult>(Func<T, TResult> func)
- Transform the success valueBind<TResult>(Func<T, Result<TResult>> func)
- Chain operations with error propagationMatch<TResult>(Func<T, TResult> onSuccess, Func<string, TResult> onFailure)
- Pattern matchingTap(Action<T> action)
- Execute side effects without changing the resultTapError(Action<string> action)
- Execute side effects on errorIsSuccess
- Check if result is successfulIsFailure
- Check if result has failedValue
- Get the success value (throws if failed)Error
- Get the error message (empty if successful)
Option<T> Methods
Some<T>(T value)
- Create an option with valueNone<T>()
- Create an empty optionMap<TResult>(Func<T, TResult> func)
- Transform the value if presentBind<TResult>(Func<T, Option<TResult>> func)
- Chain operationsFilter(Func<T, bool> predicate)
- Filter based on conditionMatch<TResult>(Func<T, TResult> onSome, Func<TResult> onNone)
- Pattern matchingGetValueOrDefault(T defaultValue)
- Get value or defaultOrElse(Func<Option<T>> alternative)
- Provide alternative optionHasValue
- Check if option has a valueValue
- Get the value (throws if empty)
Try<T> Methods
Execute<T>(Func<T> func)
- Execute function with exception handlingExecuteAsync<T>(Func<Task<T>> func)
- Execute async function with exception handlingExecuteWithRetry<T>(Func<T> func, int maxAttempts, int delayMs)
- Execute with retry logicExecuteWithCircuitBreaker<T>(Func<T> func, int failureThreshold, int timeoutMs)
- Execute with circuit breakerExecuteCompositeOperation<T>(params Func<T>[] operations)
- Execute multiple operations as compositeMap<TResult>(Func<T, TResult> func)
- Transform success valueMatch<TResult>(Func<T, TResult> onSuccess, Func<Exception, TResult> onFailure)
- Pattern matching
Either<TLeft, TRight> Methods
Left<TLeft, TRight>(TLeft left)
- Create left-side eitherRight<TLeft, TRight>(TRight right)
- Create right-side eitherMatch<TResult>(Func<TLeft, TResult> onLeft, Func<TRight, TResult> onRight)
- Pattern matchingMapLeft<TLeftResult>(Func<TLeft, TLeftResult> func)
- Transform left valueMapRight<TRightResult>(Func<TRight, TRightResult> func)
- Transform right valueIsLeft
- Check if either is left-sideIsRight
- Check if either is right-side
Ensure<T> Methods
That<T>(T value)
- Start validation chainIsNotNull(string message = null)
- Ensure value is not nullIsNotNullOrEmpty(string message = null)
- Ensure string is not null or emptySatisfies(Func<T, bool> predicate, string message)
- Custom validationIsGreaterThan<TComparable>(TComparable threshold, string message)
- Compare valuesIsInRange<TComparable>(TComparable min, TComparable max, string message)
- Range validationTransform<TResult>(Func<T, TResult> transform)
- Transform validated valueValue
- Get the validated value (throws if validation failed)
Extension Methods
// Nullable conversions
string? nullable = GetNullableString();
var option = nullable.ToOption();
var result = option.ToResult("Value was null");
// Async operations
var asyncResult = await GetUserAsync(id)
.MapAsync(user => user.Email)
.BindAsync(ValidateEmailAsync)
.TapAsync(email => LogEmailValidation(email));
// Collection operations
var results = await items
.SelectAsync(ProcessItemAsync)
.WhereSuccess()
.CollectResults();
// Entity Framework integrations
var user = await dbContext.Users
.FirstOrDefaultAsync(u => u.Id == id)
.ToResult("User not found")
.Bind(ValidateUserPermissions);
🏗️ Requirements & Compatibility
- .NET 8.0 or later
- C# 10.0 or later
- Compatible with: ASP.NET Core, Entity Framework Core, Blazor, MAUI
- Supports: Windows, Linux, macOS, Docker containers
- Tested on: Azure, AWS, Google Cloud Platform
� Intellectual Property & Licensing
MonadicSharp is protected under LGPL-3.0-or-later license with comprehensive intellectual property safeguards:
✅ What You CAN Do:
- ✅ Use MonadicSharp in commercial applications
- ✅ Distribute applications that use MonadicSharp
- ✅ Modify MonadicSharp for internal use
- ✅ Create proprietary software that uses MonadicSharp as a library
❌ What You CANNOT Do:
- ❌ Copy or redistribute MonadicSharp code without attribution
- ❌ Create derivative works without sharing modifications under LGPL
- ❌ Remove or modify copyright notices and license headers
- ❌ Use MonadicSharp trademarks without permission
🛡️ Advanced Protection Features:
- Digital Signatures: All releases are cryptographically signed
- Integrity Verification: Built-in tampering detection mechanisms
- Attribution Tracking: Embedded copyright and authorship information
- License Compliance: Automated license validation and reporting
📋 Legal Note: This library includes sophisticated anti-piracy and intellectual property protection measures. Unauthorized copying, modification, or redistribution may result in legal action. For commercial licensing inquiries, please contact the author.
For complete licensing details, see LICENSE and Documentation/ATTRIBUTION.md.
📄 Documentation
- Attribution Guide - Proper attribution and usage guidelines
- Integrity Verification - Library integrity and security information
- API Documentation - Complete API reference
- Examples Repository - Comprehensive usage examples
🤝 Contributing & Support
We welcome contributions from the community! Here's how you can help:
🔧 Contributing Guidelines
- Fork the repository and create a feature branch
- Follow the existing code style and patterns
- Add tests for any new functionality
- Update documentation as needed
- Submit a pull request with clear description
🐛 Bug Reports
- Use the GitHub issue tracker
- Provide detailed reproduction steps
- Include environment information (.NET version, OS, etc.)
- Add relevant code samples
💡 Feature Requests
- Describe the use case and benefit
- Provide example API usage
- Explain why it fits MonadicSharp's philosophy
📞 Support Channels
- GitHub Issues: Bug reports and feature requests
- NuGet Comments: Package-specific feedback
- Email: Contact via GitHub profile
🎓 Learning Resources
📚 Functional Programming in C#
- Railway-Oriented Programming - The foundational concept
- Functional Programming in C# - Microsoft's guide
- Monads Explained - Eric Lippert's series
🔗 Related Projects & Inspiration
- F# Core Library - Inspiration for functional patterns
- Haskell - Source of monadic concepts
- Rust's Result<T, E> - Error handling inspiration
- Scala's Option[T] - Optional value handling
📖 Design Philosophy
MonadicSharp follows these core principles:
- Explicit Error Handling - Make errors visible and manageable
- Composability - Operations should chain naturally
- Type Safety - Leverage the compiler to prevent runtime errors
- Readability - Code should express intent clearly
- Performance - Zero-cost abstractions where possible
🏆 About the Author
MonadicSharp is crafted with passion by Danny4897 (aka Klexir on NuGet).
🎯 Mission Statement
"To bring the elegance and safety of functional programming to the C# ecosystem, making robust error handling and null safety accessible to every .NET developer."
📈 Stats & Recognition
- 🏅 Active NuGet Publisher with multiple successful packages
- 🌟 Open Source Contributor to the .NET community
- 🎓 Functional Programming Advocate and educator
- 💼 Enterprise Software Developer with production experience
Made with ❤️ and lots of ☕ by Danny4897
"Write code that handles failure gracefully, and success will follow."
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. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.EntityFrameworkCore (>= 8.0.2)
- Microsoft.Extensions.Hosting (>= 8.0.1)
- System.Text.Json (>= 8.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
v1.3.3: Minor release with improvements and bug fixes
v1.3.2: Enhanced IP protection with integrity verification, anti-tampering measures, and comprehensive copyright headers across all files
v1.3.1: Enhanced legal protection - Updated to LGPL-3.0 license for better IP protection while maintaining commercial usability
v1.3.0: Complete rebranding from FunctionalSharp to MonadicSharp - Templates, documentation, and package naming fully unified
v1.2.0: Changed namespace from FunctionalSharp to MonadicSharp to match NuGet package name
v1.1.0: Added Either<TLeft, TRight> type for representing two alternative types