Skip to content

bbesli/PassR

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

16 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

PassR 🧭

A lightweight, flexible mediator library for .NET applications β€” designed with Clean Architecture in mind.


✨ Overview

PassR is a minimal, fast, and extensible .NET library that enables clean separation of concerns using the Mediator pattern.
Inspired by MediatR, PassR adds support for:

  • βœ… Request/response handling (IRequest, IRequestHandler)
  • βœ… Fire-and-forget notifications (INotification, INotificationHandler)
  • βœ… Middleware pipeline behaviors (IPipelineBehavior)
  • βœ… Clean and testable architecture, built on top of dependency injection
  • βœ… Command & Query separation via ICommand, IQuery abstractions

πŸ“¦ Installation

dotnet add package Verbytes.PassR

πŸ›  Setup

Register PassR and presentation services in your Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddPresentation();
builder.Services.AddPassR(options =>
{
    options.RegisterServicesFromAssembly(typeof(CreateUserCommandHandler).Assembly);
    options.AddOpenBehavior(typeof(LoggingBehavior<,>));
});
builder.Services.AddEndpoints(Assembly.GetExecutingAssembly());

πŸ›£οΈ API Pipeline Bootstrapping

You can set up the full API versioning + exception handler + Swagger pipeline with a single method:

var app = builder.Build();
 
app.UsePassRPresentation(endpointAssembly: typeof(IEndpoint).Assembly);

This configures:

  • API versioning using route segments (/api/v1/...)
  • Swagger UI with support for multiple versions
  • Automatic endpoint discovery via IEndpoint implementations
  • Custom exception middleware with problem response output

πŸ“ Basic Usage

1. Define a Request

public record GetUserQuery(Guid UserId) : IQuery<UserDto>;

2. Create a Handler

public class GetUserQueryHandler : IQueryHandler<GetUserQuery, UserDto>
{
    public async ValueTask<Result<UserDto>> HandleAsync(GetUserQuery request, CancellationToken cancellationToken)
    {
        // simulate user retrieval
        return Result.Success(new UserDto(request.UserId, "burak@example.com"));
    }
}

3. Send the Request

var result = await mediator.SendAsync(new GetUserQuery(Guid.NewGuid()));

πŸ” Notification Handling

public record UserCreated(Guid UserId) : INotification;

public class SendWelcomeEmailHandler : INotificationHandler<UserCreated>
{
    public ValueTask HandleAsync(UserCreated notification, CancellationToken cancellationToken)
    {
        Console.WriteLine($"Sending email to user: {notification.UserId}");
        return ValueTask.CompletedTask;
    }
}

Publish with:

await mediator.PublishAsync(new UserCreated(userId));

🧩 Pipeline Behaviors

public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    where TRequest : IRequest<TResponse>
{
    public async ValueTask<TResponse> HandleAsync(
        TRequest request,
        CancellationToken cancellationToken,
        RequestHandlerDelegate<TResponse> next)
    {
        Console.WriteLine($"[START] {typeof(TRequest).Name}");
        var response = await next();
        Console.WriteLine($"[END] {typeof(TRequest).Name}");
        return response;
    }
}

πŸ”€ Built-in Minimal API Versioning with Swagger UI

PassR now supports automatic API versioning for Minimal APIs with seamless Swagger integration.

βœ… Features

  • Annotate your endpoint class with [ApiVersion(x)] (e.g. [ApiVersion(2)])
  • PassR dynamically detects all versions (v1, v2, v3...) without hardcoding
  • Endpoints are grouped under /api/v{version} automatically
  • Swagger UI displays version tabs for each registered version

πŸš€ Example

[ApiVersion(2)]
public class PostTestV2 : IEndpoint
{
    public void MapEndpoint(IEndpointRouteBuilder app)
    {
        app.MapPost("PostTest", ...)
            .WithTags("Tests")
    }
}

No need to configure versions manually. Just use:

var app = builder.Build();

app.UsePassRPresentation(Assembly.GetExecutingAssembly());

Enjoy fully dynamic, scalable API versioning with clean Swagger support.


πŸ“š Interfaces Overview

Interface Purpose
IRequest<TResponse> Represents a request with a response
IRequestHandler<,> Handles a request
INotification Represents a fire-and-forget event
INotificationHandler<> Handles a notification
IPipelineBehavior<,> Middleware logic around requests
ICommand, IQuery CQRS-style abstractions
Result, Error, ValidationError Functional result pattern

πŸ§ͺ Example Projects

Check out /examples/WebAPI for how to:

  • Wire up PassR into a minimal API project
  • Use commands, queries, notifications
  • Add pipeline logging
  • Validate using a behavior layer

πŸ“„ License

MIT Β© Burak Besli

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages