Skip to content

mhalikosen/ulak

Repository files navigation

Ulak

NuGet NuGet Downloads

Lightweight CQRS mediator library for .NET.

Installation

dotnet add package Ulak

Requires .NET 10+.

Quick Start

1. Define commands and queries

public record CreateUser(string Name, string Email) : ICommand;

public record CreateOrder(Guid UserId, decimal Amount) : ICommand<Guid>;

public record GetUser(Guid Id) : IQuery<UserDto>;

2. Implement handlers

public class CreateUserHandler : ICommandHandler<CreateUser>
{
    public async Task HandleAsync(CreateUser command, CancellationToken cancellationToken)
    {
        // create user...
    }
}

public class CreateOrderHandler : ICommandHandler<CreateOrder, Guid>
{
    public async Task<Guid> HandleAsync(CreateOrder command, CancellationToken cancellationToken)
    {
        // create order, return id...
    }
}

public class GetUserHandler : IQueryHandler<GetUser, UserDto>
{
    public async Task<UserDto> HandleAsync(GetUser query, CancellationToken cancellationToken)
    {
        // fetch user...
    }
}

3. Register services

builder.Services.AddUlak();

Handlers are discovered automatically from all loaded assemblies.

4. Send requests

app.MapPost("/users", async (CreateUser command, ISender sender) =>
{
    await sender.SendAsync(command);
    return Results.Created();
});

app.MapPost("/orders", async (CreateOrder command, ISender sender) =>
{
    var orderId = await sender.SendAsync(command);
    return Results.Created($"/orders/{orderId}", new { id = orderId });
});

app.MapGet("/users/{id}", async (Guid id, ISender sender) =>
{
    var user = await sender.SendAsync(new GetUser(id));
    return Results.Ok(user);
});

5. Pipeline behaviors (optional)

Behaviors run in registration order, wrapping the handler in a pipeline.

public class LoggingBehavior : IPipelineBehavior
{
    public async Task<TResponse> HandleAsync<TRequest, TResponse>(
        TRequest request,
        NextStep<TResponse> next,
        CancellationToken cancellationToken)
        where TRequest : IRequest<TResponse>
    {
        Console.WriteLine($"Handling {typeof(TRequest).Name}");
        var response = await next();
        Console.WriteLine($"Handled {typeof(TRequest).Name}");
        return response;
    }
}

builder.Services.AddUlak(options =>
{
    options.AddBehavior<LoggingBehavior>();
    options.AddBehavior<ValidationBehavior>();
});

License

MIT

About

Lightweight CQRS mediator library for .NET

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages