VOOZH about

URL: https://www.nuget.org/packages/DKNet.SlimBus.Extensions/

⇱ NuGet Gallery | DKNet.SlimBus.Extensions 10.0.27




👁 Image
DKNet.SlimBus.Extensions 10.0.27

dotnet add package DKNet.SlimBus.Extensions --version 10.0.27
 
 
NuGet\Install-Package DKNet.SlimBus.Extensions -Version 10.0.27
 
 
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="DKNet.SlimBus.Extensions" Version="10.0.27" />
 
 
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DKNet.SlimBus.Extensions" Version="10.0.27" />
 
Directory.Packages.props
<PackageReference Include="DKNet.SlimBus.Extensions" />
 
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 DKNet.SlimBus.Extensions --version 10.0.27
 
 
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: DKNet.SlimBus.Extensions, 10.0.27"
 
 
#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 DKNet.SlimBus.Extensions@10.0.27
 
 
#: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=DKNet.SlimBus.Extensions&version=10.0.27
 
Install as a Cake Addin
#tool nuget:?package=DKNet.SlimBus.Extensions&version=10.0.27
 
Install as a Cake Tool
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

DKNet.SlimBus.Extensions

👁 NuGet
👁 NuGet Downloads
👁 .NET

Enhanced SlimMessageBus integration with Entity Framework Core, providing fluent interfaces for CQRS patterns, automatic transaction management, and result-based error handling. This package bridges SlimMessageBus with EF Core for seamless domain-driven applications.

Features

  • CQRS Fluent Interfaces: Strongly-typed request/query handlers with result patterns
  • EF Core Integration: Automatic SaveChanges after successful request processing
  • Result Pattern Support: Built-in FluentResults integration for error handling
  • Transaction Management: Automatic transaction handling with rollback on failures
  • Query Abstractions: Specialized interfaces for queries vs commands
  • Pagination Support: Built-in support for paged query results
  • Event Consumer Abstractions: Fluent interfaces for domain event handling
  • Auto-Save Behavior: Intelligent EF Core change detection and persistence

Supported Frameworks

  • .NET 9.0+
  • Entity Framework Core 9.0+
  • SlimMessageBus 2.0+
  • FluentResults 3.0+

Installation

Install via NuGet Package Manager:

dotnet add package DKNet.SlimBus.Extensions

Or via Package Manager Console:

Install-Package DKNet.SlimBus.Extensions

Quick Start

Setup SlimBus with EF Core

using Microsoft.Extensions.DependencyInjection;
using DKNet.SlimBus.Extensions;

// Configure SlimBus with EF Core integration
services.AddSlimBusForEfCore(builder =>
{
 builder
 .WithProviderMemory() // or other providers
 .AutoDeclareFrom(typeof(CreateProductHandler).Assembly)
 .AddJsonSerializer();
});

// Add your DbContext
services.AddDbContext<AppDbContext>(options =>
 options.UseSqlServer(connectionString));

Command Handler with Result Pattern

using DKNet.SlimBus.Extensions;
using FluentResults;

// Command definition
public record CreateProduct : Fluents.Requests.IWitResponse<ProductResult>
{
 public required string Name { get; init; }
 public required decimal Price { get; init; }
 public required string CategoryId { get; init; }
}

public record ProductResult
{
 public required Guid Id { get; init; }
 public required string Name { get; init; }
 public required decimal Price { get; init; }
}

// Command handler
public class CreateProductHandler : Fluents.Requests.IHandler<CreateProduct, ProductResult>
{
 private readonly AppDbContext _context;
 private readonly IMapper _mapper;

 public CreateProductHandler(AppDbContext context, IMapper mapper)
 {
 _context = context;
 _mapper = mapper;
 }

 public async Task<IResult<ProductResult>> Handle(CreateProduct request, CancellationToken cancellationToken)
 {
 // Validation
 if (await _context.Products.AnyAsync(p => p.Name == request.Name, cancellationToken))
 return Result.Fail<ProductResult>($"Product with name '{request.Name}' already exists");

 // Create entity
 var product = new Product(request.Name, request.Price, request.CategoryId);
 _context.Products.Add(product);
 
 // EF Core SaveChanges is called automatically after successful processing
 
 return Result.Ok(_mapper.Map<ProductResult>(product));
 }
}

Query Handler

using DKNet.SlimBus.Extensions;

// Query definition
public record GetProduct : Fluents.Queries.IWitResponse<ProductResult>
{
 public required Guid Id { get; init; }
}

// Query handler (no auto-save for queries)
public class GetProductHandler : Fluents.Queries.IHandler<GetProduct, ProductResult>
{
 private readonly AppDbContext _context;
 private readonly IMapper _mapper;

 public GetProductHandler(AppDbContext context, IMapper mapper)
 {
 _context = context;
 _mapper = mapper;
 }

 public async Task<ProductResult?> Handle(GetProduct request, CancellationToken cancellationToken)
 {
 var product = await _context.Products
 .FirstOrDefaultAsync(p => p.Id == request.Id, cancellationToken);
 
 return product == null ? null : _mapper.Map<ProductResult>(product);
 }
}

Paged Query Handler

using X.PagedList;
using DKNet.SlimBus.Extensions;

// Paged query definition
public record GetProductsPage : Fluents.Queries.IWitPageResponse<ProductResult>
{
 public int PageIndex { get; init; } = 0;
 public int PageSize { get; init; } = 20;
 public string? CategoryId { get; init; }
}

// Paged query handler
public class GetProductsPageHandler : Fluents.Queries.IPageHandler<GetProductsPage, ProductResult>
{
 private readonly AppDbContext _context;
 private readonly IMapper _mapper;

 public GetProductsPageHandler(AppDbContext context, IMapper mapper)
 {
 _context = context;
 _mapper = mapper;
 }

 public async Task<IPagedList<ProductResult>> Handle(GetProductsPage request, CancellationToken cancellationToken)
 {
 var query = _context.Products.AsQueryable();
 
 if (!string.IsNullOrEmpty(request.CategoryId))
 query = query.Where(p => p.CategoryId == request.CategoryId);
 
 return await query
 .OrderBy(p => p.Name)
 .Select(p => _mapper.Map<ProductResult>(p))
 .ToPagedListAsync(request.PageIndex, request.PageSize, cancellationToken);
 }
}

Configuration

Handler Registration

// Handlers are automatically discovered and registered
services.AddSlimBusForEfCore(builder =>
{
 builder
 .WithProviderMemory()
 // Auto-discover handlers from assemblies
 .AutoDeclareFrom(typeof(CreateProductHandler).Assembly, typeof(GetProductHandler).Assembly)
 .AddJsonSerializer();
});

Custom Behaviors and Interceptors

using SlimMessageBus.Host.Interceptor;

public class ValidationInterceptor<TRequest, TResponse> : IRequestHandlerInterceptor<TRequest, TResponse>
{
 private readonly IValidator<TRequest> _validator;

 public ValidationInterceptor(IValidator<TRequest> validator)
 {
 _validator = validator;
 }

 public async Task<TResponse> OnHandle(TRequest request, Func<Task<TResponse>> next, IConsumerContext context)
 {
 // Validate request
 var validationResult = await _validator.ValidateAsync(request, context.CancellationToken);
 if (!validationResult.IsValid)
 {
 if (typeof(TResponse).IsAssignableFrom(typeof(IResultBase)))
 {
 var errors = validationResult.Errors.Select(e => e.ErrorMessage);
 return (TResponse)(object)Result.Fail(errors);
 }
 throw new ValidationException(validationResult.Errors);
 }

 return await next();
 }
}

// Register the interceptor
services.AddScoped(typeof(IRequestHandlerInterceptor<,>), typeof(ValidationInterceptor<,>));

API Reference

Request Interfaces

  • Fluents.Requests.INoResponse - Commands that don't return data
  • Fluents.Requests.IWitResponse<TResponse> - Commands that return data
  • Fluents.Requests.IHandler<TRequest> - Handler for no-response commands
  • Fluents.Requests.IHandler<TRequest, TResponse> - Handler for commands with response

Query Interfaces

  • Fluents.Queries.IWitResponse<TResponse> - Single-item queries
  • Fluents.Queries.IWitPageResponse<TResponse> - Paged queries
  • Fluents.Queries.IHandler<TQuery, TResponse> - Single-item query handler
  • Fluents.Queries.IPageHandler<TQuery, TResponse> - Paged query handler

Event Interfaces

  • Fluents.EventsConsumers.IHandler<TEvent> - Domain event handler

EF Core Integration

  • AddSlimBusForEfCore() - Register SlimBus with EF Core auto-save
  • EfAutoSavePostProcessor<,> - Automatic SaveChanges after successful commands

Advanced Usage

Event Handler with Domain Events

using DKNet.SlimBus.Extensions;

// Domain event
public record ProductCreatedEvent(Guid ProductId, string Name, decimal Price);

// Event handler
public class ProductCreatedHandler : Fluents.EventsConsumers.IHandler<ProductCreatedEvent>
{
 private readonly ILogger<ProductCreatedHandler> _logger;
 private readonly IEmailService _emailService;

 public ProductCreatedHandler(ILogger<ProductCreatedHandler> logger, IEmailService emailService)
 {
 _logger = logger;
 _emailService = emailService;
 }

 public async Task Handle(ProductCreatedEvent notification, CancellationToken cancellationToken)
 {
 _logger.LogInformation("Product created: {ProductId} - {Name}", notification.ProductId, notification.Name);
 
 // Send notification email
 await _emailService.SendProductCreatedNotificationAsync(notification.ProductId, cancellationToken);
 }
}

Complex Command with Multiple Operations

public record ProcessOrder : Fluents.Requests.IWitResponse<OrderResult>
{
 public required Guid CustomerId { get; init; }
 public required List<OrderItemRequest> Items { get; init; }
}

public class ProcessOrderHandler : Fluents.Requests.IHandler<ProcessOrder, OrderResult>
{
 private readonly AppDbContext _context;
 private readonly IInventoryService _inventoryService;
 private readonly IPaymentService _paymentService;

 public ProcessOrderHandler(AppDbContext context, IInventoryService inventoryService, IPaymentService paymentService)
 {
 _context = context;
 _inventoryService = inventoryService;
 _paymentService = paymentService;
 }

 public async Task<IResult<OrderResult>> Handle(ProcessOrder request, CancellationToken cancellationToken)
 {
 // Validate inventory
 var inventoryCheck = await _inventoryService.CheckAvailabilityAsync(request.Items, cancellationToken);
 if (!inventoryCheck.IsSuccess)
 return Result.Fail<OrderResult>(inventoryCheck.Errors);

 // Create order
 var order = new Order(request.CustomerId);
 foreach (var item in request.Items)
 {
 order.AddItem(item.ProductId, item.Quantity, item.Price);
 }
 
 _context.Orders.Add(order);

 // Process payment
 var paymentResult = await _paymentService.ProcessPaymentAsync(order.TotalAmount, cancellationToken);
 if (!paymentResult.IsSuccess)
 return Result.Fail<OrderResult>(paymentResult.Errors);

 order.MarkAsPaid(paymentResult.Value.TransactionId);
 
 // EF Core will auto-save all changes if no errors occur
 
 return Result.Ok(new OrderResult 
 { 
 OrderId = order.Id, 
 TotalAmount = order.TotalAmount,
 Status = order.Status 
 });
 }
}

Error Handling

The package uses FluentResults for comprehensive error handling:

public async Task<IResult<ProductResult>> Handle(CreateProduct request, CancellationToken cancellationToken)
{
 // Business rule validation
 if (request.Price <= 0)
 return Result.Fail<ProductResult>("Price must be greater than zero");

 // Multiple validation errors
 var errors = new List<string>();
 if (string.IsNullOrEmpty(request.Name))
 errors.Add("Name is required");
 if (request.Price <= 0)
 errors.Add("Price must be positive");
 
 if (errors.Any())
 return Result.Fail<ProductResult>(errors);

 // Success case
 var product = new Product(request.Name, request.Price);
 _context.Products.Add(product);
 
 return Result.Ok(_mapper.Map<ProductResult>(product));
}

Transaction Behavior

  • Commands: Automatic SaveChanges after successful processing
  • Queries: No SaveChanges (read-only operations)
  • Failures: Automatic rollback if any step fails
  • Multiple DbContexts: All contexts with changes are saved atomically

Performance Considerations

  • Change Tracking: Only contexts with changes trigger SaveChanges
  • Query Optimization: Queries bypass transaction overhead
  • Pagination: Efficient database paging with X.PagedList
  • Result Patterns: Minimal overhead with compile-time safety

Thread Safety

  • Handlers should be stateless for thread safety
  • DbContext instances are scoped per request
  • SlimMessageBus handles concurrency according to its configuration

Contributing

See the main for guidelines on how to contribute to this project.

License

This project is licensed under the .

Related Packages

  • - EF Core functionality extensions
  • - Domain event handling and dispatching
  • - Framework-level extensions

Part of the DKNet Framework - A comprehensive .NET framework for building modern, scalable applications.

Product Versions Compatible and additional computed target framework versions.
.NET net10.0 net10.0 is compatible.  net10.0-android net10.0-android was computed.  net10.0-browser net10.0-browser was computed.  net10.0-ios net10.0-ios was computed.  net10.0-maccatalyst net10.0-maccatalyst was computed.  net10.0-macos net10.0-macos was computed.  net10.0-tvos net10.0-tvos was computed.  net10.0-windows 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 (1)

Showing the top 1 NuGet packages that depend on DKNet.SlimBus.Extensions:

Package Downloads
DKNet.AspCore.SlimBus

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.0.27 144 5/22/2026
10.0.26 100 5/19/2026
10.0.25 430 3/27/2026
10.0.24 112 3/27/2026
10.0.23 120 3/27/2026
10.0.22 110 3/26/2026
10.0.21 158 3/17/2026
10.0.20 143 2/2/2026
10.0.19 262 1/21/2026
10.0.18 120 1/21/2026
10.0.17 149 1/19/2026
10.0.16 123 1/18/2026
10.0.15 122 1/18/2026
10.0.14 115 1/18/2026
10.0.13 120 1/17/2026
10.0.12 118 1/17/2026
10.0.11 133 1/17/2026
10.0.10 114 1/17/2026
10.0.9 136 1/16/2026
10.0.8 124 1/16/2026
Loading failed