UseCasePipeline 1.0.9

dotnet add package UseCasePipeline --version 1.0.9
                    
NuGet\Install-Package UseCasePipeline -Version 1.0.9
                    
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="UseCasePipeline" Version="1.0.9" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="UseCasePipeline" Version="1.0.9" />
                    
Directory.Packages.props
<PackageReference Include="UseCasePipeline" />
                    
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 UseCasePipeline --version 1.0.9
                    
#r "nuget: UseCasePipeline, 1.0.9"
                    
#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 UseCasePipeline@1.0.9
                    
#: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=UseCasePipeline&version=1.0.9
                    
Install as a Cake Addin
#tool nuget:?package=UseCasePipeline&version=1.0.9
                    
Install as a Cake Tool

UseCasePipeline

A lightweight UseCase pipeline library for .NET 8+. Implement clean, structured use cases with built-in support for request validation, entity validation, rule enforcement, authorisation, custom pipes, and a mediator — all wired up automatically via DI.

Installation

dotnet add package UseCasePipeline

Getting Started

1. Register the pipeline

In Program.cs, call AddUseCasePipeline() with no arguments. It automatically scans every assembly in your app that references this library:

using UseCasePipeline.Extensions;
using UseCasePipeline.Middleware;

builder.Services.AddUseCasePipeline();

var app = builder.Build();

// Optional: maps pipeline exceptions to HTTP responses automatically
app.UseUseCasePipelineExceptionHandler();

2. Define a request and response

using UseCasePipeline.Infrastructure;

public class CreateOrderRequest : IUseCaseRequest<CreateOrderResponse>
{
    public Guid CustomerId { get; set; }
    public List<Guid> ProductIds { get; set; } = [];
}

public class CreateOrderResponse : IUseCaseResponse
{
    public Guid OrderId { get; set; }
}

3. Implement the handler

using UseCasePipeline.Infrastructure;

public class CreateOrderHandler : IUseCaseHandler<CreateOrderRequest, CreateOrderResponse>
{
    public async Task<CreateOrderResponse> Handle(CreateOrderRequest request, CancellationToken cancellationToken)
    {
        // core use case logic
        return new CreateOrderResponse { OrderId = Guid.NewGuid() };
    }
}

4. Add optional pipeline stages

All stages are optional. Register as many as you need per use case.

Request Validator — validates the incoming request data:

public class CreateOrderRequestValidator : IUseCaseRequestValidator<CreateOrderRequest>
{
    public Task Validate(CreateOrderRequest request, CancellationToken cancellationToken)
    {
        if (request.ProductIds.Count == 0)
            throw new UseCaseValidationException("At least one product is required.");

        return Task.CompletedTask;
    }
}

Entity Validator — checks required entities exist before the handler runs:

public class CreateOrderEntityValidator : IUseCaseEntityValidator<CreateOrderRequest>
{
    public async Task Validate(CreateOrderRequest request, CancellationToken cancellationToken)
    {
        var customer = await _repo.FindCustomerAsync(request.CustomerId);
        if (customer is null)
            throw new UseCaseEntityNotFoundException(nameof(Customer), request.CustomerId);
    }
}

Authoriser — enforces permissions:

public class CreateOrderAuthoriser : IUseCaseAuthoriser<CreateOrderRequest>
{
    public Task Authorise(CreateOrderRequest request, CancellationToken cancellationToken)
    {
        if (!_currentUser.CanCreateOrders)
            throw new UseCaseAuthorisationException();

        return Task.CompletedTask;
    }
}

Rule Enforcer — enforces business rules after validation and before the handler runs:

public class CreateOrderRuleEnforcer : IUseCaseRuleEnforcer<CreateOrderRequest>
{
    public Task Enforce(CreateOrderRequest request, CancellationToken cancellationToken)
    {
        if (!_orderingRules.CustomerCanPlaceOrder(request.CustomerId))
            throw new UseCaseRuleViolationException("Customer cannot place orders at this time.");

        return Task.CompletedTask;
    }
}

Custom Pipe - runs custom use-case pipeline logic after the built-in authorisation, validation, entity validation, and rule enforcement stages, but before the handler:

public class CreateOrderAuditPipe : IUseCaseCustomPipe<CreateOrderRequest>
{
    public Task InvokeAsync(CreateOrderRequest request, CancellationToken cancellationToken)
    {
        // custom pipeline logic, such as auditing, enrichment, or instrumentation
        return Task.CompletedTask;
    }
}

5. Send a request

Inject UseCaseMediator and call Send. The response type is inferred automatically:

public class OrdersController(UseCaseMediator mediator) : ControllerBase
{
    [HttpPost]
    public async Task<IActionResult> Create(CreateOrderRequest request, CancellationToken cancellationToken)
    {
        var response = await mediator.Send(request, cancellationToken);
        return Ok(response);
    }
}

Pipeline Execution Order

For every Send call the pipeline runs stages in this order:

Authoriser(s) -> Request Validator(s) -> Entity Validator(s) -> Rule Enforcer(s) -> Custom Pipe(s) -> Handler

All stages are optional. Multiple implementations of the same stage are all executed sequentially in registration order.

Exception Middleware

UseUseCasePipelineExceptionHandler() catches pipeline exceptions and maps them to HTTP responses:

Exception Status Code
UseCaseValidationException 400 Bad Request
UseCaseEntityNotFoundException 404 Not Found
UseCaseAuthorisationException 403 Forbidden
UseCaseRuleViolationException 400 Bad Request
Any other exception Propagates unhandled

Command-style Use Cases (no response)

For use cases that produce no result, implement IUseCaseRequest and IUseCaseHandler<TRequest> directly:

public class DeleteOrderRequest : IUseCaseRequest
{
    public Guid OrderId { get; set; }
}

public class DeleteOrderHandler : IUseCaseHandler<DeleteOrderRequest>
{
    public async Task Handle(DeleteOrderRequest request, CancellationToken cancellationToken)
    {
        // delete logic
    }
}

// Send with no return value
await mediator.Send(new DeleteOrderRequest { OrderId = id });

License

MIT

Product 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. 
Compatible target framework(s)
Included target framework(s) (in 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.9 102 5/18/2026
1.0.8 120 5/4/2026
1.0.7 91 5/2/2026
1.0.6 93 5/2/2026
1.0.5 103 5/2/2026
1.0.4 95 5/2/2026