![]() |
VOOZH | about |
dotnet add package DKNet.SlimBus.Extensions --version 10.0.27
NuGet\Install-Package DKNet.SlimBus.Extensions -Version 10.0.27
<PackageReference Include="DKNet.SlimBus.Extensions" Version="10.0.27" />
<PackageVersion Include="DKNet.SlimBus.Extensions" Version="10.0.27" />Directory.Packages.props
<PackageReference Include="DKNet.SlimBus.Extensions" />Project file
paket add DKNet.SlimBus.Extensions --version 10.0.27
#r "nuget: DKNet.SlimBus.Extensions, 10.0.27"
#:package DKNet.SlimBus.Extensions@10.0.27
#addin nuget:?package=DKNet.SlimBus.Extensions&version=10.0.27Install as a Cake Addin
#tool nuget:?package=DKNet.SlimBus.Extensions&version=10.0.27Install as a Cake Tool
👁 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.
Install via NuGet Package Manager:
dotnet add package DKNet.SlimBus.Extensions
Or via Package Manager Console:
Install-Package DKNet.SlimBus.Extensions
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));
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));
}
}
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);
}
}
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);
}
}
// Handlers are automatically discovered and registered
services.AddSlimBusForEfCore(builder =>
{
builder
.WithProviderMemory()
// Auto-discover handlers from assemblies
.AutoDeclareFrom(typeof(CreateProductHandler).Assembly, typeof(GetProductHandler).Assembly)
.AddJsonSerializer();
});
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<,>));
Fluents.Requests.INoResponse - Commands that don't return dataFluents.Requests.IWitResponse<TResponse> - Commands that return dataFluents.Requests.IHandler<TRequest> - Handler for no-response commandsFluents.Requests.IHandler<TRequest, TResponse> - Handler for commands with responseFluents.Queries.IWitResponse<TResponse> - Single-item queriesFluents.Queries.IWitPageResponse<TResponse> - Paged queriesFluents.Queries.IHandler<TQuery, TResponse> - Single-item query handlerFluents.Queries.IPageHandler<TQuery, TResponse> - Paged query handlerFluents.EventsConsumers.IHandler<TEvent> - Domain event handlerAddSlimBusForEfCore() - Register SlimBus with EF Core auto-saveEfAutoSavePostProcessor<,> - Automatic SaveChanges after successful commandsusing 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);
}
}
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
});
}
}
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));
}
See the main for guidelines on how to contribute to this project.
This project is licensed under the .
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. |
Showing the top 1 NuGet packages that depend on DKNet.SlimBus.Extensions:
| Package | Downloads |
|---|---|
|
DKNet.AspCore.SlimBus
Package Description |
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 |