Handlr.SourceGenerator 1.0.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package Handlr.SourceGenerator --version 1.0.2
                    
NuGet\Install-Package Handlr.SourceGenerator -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Handlr.SourceGenerator" Version="1.0.2">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Handlr.SourceGenerator" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="Handlr.SourceGenerator">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Handlr.SourceGenerator --version 1.0.2
                    
#r "nuget: Handlr.SourceGenerator, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Handlr.SourceGenerator@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Handlr.SourceGenerator&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=Handlr.SourceGenerator&version=1.0.2
                    
Install as a Cake Tool

<div align="center"> <img src="https://raw.githubusercontent.com/sodiqyekeen/handlr/main/assets/logos/handlr-nuget-icon.svg" alt="Handlr Logo" width="128" height="128" />

Handlr - Modern CQRS Framework with Source Generator

CQRS Made Simple </div>

<div align="center">

NuGet - Handlr.Abstractions NuGet - Handlr.SourceGenerator Continuous Integration Release Security Scan Documentation

</div>

A lightweight CQRS (Command Query Responsibility Segregation) framework for .NET that provides the infrastructure for building scalable applications with automatic code generation and extensible pipeline behavior support.

📦 What's Included

Core Package (Handlr.Abstractions)

  • 🎯 CQRS Interfaces: ICommand<T>, IQuery<T>, ICommandHandler<T>, IQueryHandler<T>
  • 🔄 Pipeline Infrastructure: IPipelineBehavior<TRequest, TResponse> for cross-cutting concerns
  • 📋 Result Pattern Support: Flexible return types including Result<T> patterns
  • 🏷️ Marker Interfaces: For opt-in behavior patterns (e.g., IValidatable, ICacheable)

Source Generator (Handlr.SourceGenerator)

  • 🤖 Automatic Registration: Discovers and registers all handlers
  • 🔧 Boilerplate Generation: Eliminates manual configuration
  • Compile-time Safety: Type-safe handler discovery

Samples & Examples

  • 📚 Implementation Patterns: Real-world examples of pipeline behaviors
  • 🎨 Best Practices: Recommended approaches for common scenarios
  • 🚀 Getting Started Templates: Ready-to-use patterns for your application

🚀 Features

  • Source Generator Powered: Automatic discovery and registration of commands, queries, and handlers
  • Pipeline Behavior Support: Infrastructure and examples for implementing cross-cutting concerns
  • Type-Safe: Strong typing with compile-time validation
  • Flexible Results: Support for any return type including Result<T> pattern
  • Dependency Injection Ready: Built for modern .NET DI containers
  • Example-Driven: Rich examples and templates for rapid development

📋 Quick Start

1. Install Packages

<PackageReference Include="Handlr.Abstractions" />
<PackageReference Include="Handlr.SourceGenerator" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />

2. Define Commands and Queries

// Command
public record CreateUserCommand : ICommand<Result<User>>
{
    public string Name { get; init; } = string.Empty;
    public string Email { get; init; } = string.Empty;
    public string? CorrelationId { get; init; } = Guid.NewGuid().ToString();
    public IDictionary<string, object>? Metadata { get; init; } = new Dictionary<string, object>();
}

// Query
public record GetUserQuery : IQuery<Result<User>>
{
    public int UserId { get; init; }
    public string? CorrelationId { get; init; } = Guid.NewGuid().ToString();
    public IDictionary<string, object>? Metadata { get; init; } = new Dictionary<string, object>();
}

3. Implement Handlers (Partial Classes)

public partial class CreateUserCommandHandler
{
    public partial async Task<Result<User>> HandleAsync(CreateUserCommand command, CancellationToken cancellationToken)
    {
        // Your business logic here
        var user = new User(command.Name, command.Email);
        return Result<User>.Success(user);
    }
}

4. Register and Use

// The source generator automatically creates registration extensions
services.AddHandlr();

// Send commands and queries
var result = await handler.Send(new CreateUserCommand { Name = "John", Email = "john@example.com" });

🎯 Pipeline Behavior Examples

The framework provides the infrastructure for pipeline behaviors and includes comprehensive examples to help you implement cross-cutting concerns:

Example Behavior Patterns

Example Pattern Purpose Marker Interface Sample Implementation
Validation Request validation IValidatable Input validation with detailed error reporting
Logging Request/response logging All requests Correlation IDs, performance tracking
Caching Query result caching ICacheable Configurable cache duration and keys
Authorization Permission checking IRequireAuthorization Role/permission-based access control
Retry Transient failure handling IRetryable Exponential backoff, smart retry logic
Metrics Performance monitoring IMetricsEnabled Custom tags, success/failure tracking

Note: These are example patterns provided in the samples folder. You need to implement the actual behavior classes according to your application's needs.

Example: Command with Multiple Behaviors

public record CreateOrderCommand : ICommand<Result<Order>>, IValidatable, IRequireAuthorization, IMetricsEnabled
{
    public string ProductId { get; init; } = string.Empty;
    public int Quantity { get; init; }
    public string CustomerId { get; init; } = string.Empty;
    
    // IValidatable implementation
    public ValidationResult Validate()
    {
        var result = new ValidationResult();
        if (string.IsNullOrEmpty(ProductId)) result.AddError("ProductId required");
        if (Quantity <= 0) result.AddError("Quantity must be positive");
        return result;
    }
    
    // IRequireAuthorization implementation
    public string RequiredPermission => "Order.Create";
    public string? ResourceId => CustomerId;
    
    // IMetricsEnabled implementation
    public string OperationName => "order.create";
    public Dictionary<string, string> MetricsTags => new()
    {
        { "product_id", ProductId },
        { "quantity", Quantity.ToString() }
    };
    
    // Required ICommand properties
    public string? CorrelationId { get; init; } = Guid.NewGuid().ToString();
    public IDictionary<string, object>? Metadata { get; init; } = new Dictionary<string, object>();
}

🔧 Pipeline Behavior Registration

Handlr provides flexible pipeline behavior registration using standard .NET DI patterns. You can choose between global and selective registration approaches:

Apply behaviors to all commands and queries automatically:

// ✅ Global registration - applies to ALL commands and queries
services.AddHandlr();

// Register behaviors globally using generic type registration
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehaviorExample<,>));
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviorExample<,>));
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(MetricsBehaviorExample<,>));

// Execution order follows registration order:
// 1. LoggingBehavior → 2. ValidationBehavior → 3. MetricsBehavior → 4. Handler

Benefits:

  • Single registration per behavior type
  • Automatic coverage for all commands/queries
  • Easy maintenance - add new commands without extra registration
  • Standard .NET DI - familiar pattern for all developers

🎯 Selective Registration

Apply behaviors only to specific command/query combinations:

// ✅ Selective registration - fine-grained control
services.AddHandlr();

// Register for specific command-response combinations
services.AddScoped<IPipelineBehavior<CreateOrderCommand, Result<Order>>, AuthorizationBehaviorExample<CreateOrderCommand, Result<Order>>>();
services.AddScoped<IPipelineBehavior<CreateOrderCommand, Result<Order>>, ValidationBehaviorExample<CreateOrderCommand, Result<Order>>>();

// Different behaviors for different commands
services.AddScoped<IPipelineBehavior<GetUserQuery, Result<User>>, CachingBehaviorExample<GetUserQuery, Result<User>>>();
services.AddScoped<IPipelineBehavior<GetUserQuery, Result<User>>, LoggingBehaviorExample<GetUserQuery, Result<User>>>();

Benefits:

  • Precise control over which behaviors apply where
  • Performance optimization - only run necessary behaviors
  • Different behavior chains for different command types

🎭 Mixed Registration

Combine both approaches for maximum flexibility:

services.AddHandlr();

// Global behaviors for cross-cutting concerns
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehaviorExample<,>));
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(MetricsBehaviorExample<,>));

// Selective behaviors for specific needs
services.AddScoped<IPipelineBehavior<SecurityCommand, Result>, AuthorizationBehaviorExample<SecurityCommand, Result>>();
services.AddScoped<IPipelineBehavior<CachedQuery, Result<Data>>, CachingBehaviorExample<CachedQuery, Result<Data>>>();

🔄 Execution Order

Behaviors execute in registration order:

// Execution order: Auth → Validation → Logging → Metrics → Handler
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(AuthorizationBehaviorExample<,>));  // 1st
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviorExample<,>));     // 2nd
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehaviorExample<,>));        // 3rd
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(MetricsBehaviorExample<,>));        // 4th

💡 Best Practice: Register cross-cutting concerns (logging, metrics) globally, and specific behaviors (authorization, caching) selectively.

📚 Documentation

🏗️ Project Structure

├── src/
│   ├── Handlr.Abstractions/          # Core interfaces and abstractions
│   ├── Handlr.SourceGenerator/        # Source generator implementation
│   └── Handlr.Extensions/             # Additional extensions
├── samples/
│   ├── SampleConsoleApp/              # Console app with behavior examples
│   │   └── Examples/                  # Comprehensive behavior examples
│   └── SampleWebApi/                  # Web API example
└── tests/                             # Unit and integration tests

🎯 Architecture Principles

  1. Example-Driven Development: Framework provides examples, not implementations
  2. Source Generator First: Automatic code generation for boilerplate
  3. Interface-Based Behaviors: Opt-in behaviors through marker interfaces
  4. Pipeline Architecture: Composable behaviors with clear execution order
  5. Type Safety: Compile-time validation and strong typing

🚀 Getting Started

  1. Explore Examples: Check out samples/SampleConsoleApp/Examples/ for comprehensive behavior examples
  2. Copy and Adapt: Use examples as starting points for your implementations
  3. Understand Patterns: Review the Pipeline Behaviors Guide
  4. Build Your App: Apply the patterns to your specific use cases

🔧 What You Can Build

With Handlr's pipeline behavior infrastructure, you can implement:

  • Conditional Behaviors: Apply behaviors based on environment or configuration
  • Behavior Composition: Combine multiple concerns in single behaviors
  • Dynamic Selection: Choose behaviors based on request properties
  • Performance Monitoring: Custom metrics and performance tracking
  • Error Handling: Comprehensive exception handling patterns

Note: These are capabilities you can implement using the provided infrastructure and example patterns.

📖 Learn More

  • Run dotnet run in samples/SampleConsoleApp to see the framework in action
  • Explore behavior examples in samples/SampleConsoleApp/Examples/
  • Read the comprehensive behaviors documentation

Samples

Check out the samples directory for complete working examples:

Contributing

We welcome contributions! Please see our Contributing Guide for details.

🔄 CI/CD Pipeline

This project uses a comprehensive CI/CD pipeline with:

  • Continuous Integration: Automated testing on .NET 9.0
  • Automated Releases: Semantic versioning with auto-generated changelogs
  • Security Scanning: Vulnerability detection and secret scanning
  • Documentation: Auto-generated API docs deployed to GitHub Pages

See CI/CD Pipeline Documentation for complete details.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support


The Handlr framework makes it easy to build maintainable, scalable applications with clean CQRS patterns and powerful cross-cutting concerns.

Built with ❤️ by Sodiq Yekeen

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.5 365 9/18/2025
1.0.4 564 9/17/2025
1.0.3 410 9/14/2025
1.0.2 390 9/14/2025
1.0.1 392 9/14/2025
1.0.0 400 9/13/2025
0.1.1 408 9/14/2025

Initial release of Handlr - CQRS Source Generator