RA.Utilities.Feature
10.0.1
Prefix Reserved
dotnet add package RA.Utilities.Feature --version 10.0.1
NuGet\Install-Package RA.Utilities.Feature -Version 10.0.1
<PackageReference Include="RA.Utilities.Feature" Version="10.0.1" />
<PackageVersion Include="RA.Utilities.Feature" Version="10.0.1" />
<PackageReference Include="RA.Utilities.Feature" />
paket add RA.Utilities.Feature --version 10.0.1
#r "nuget: RA.Utilities.Feature, 10.0.1"
#:package RA.Utilities.Feature@10.0.1
#addin nuget:?package=RA.Utilities.Feature&version=10.0.1
#tool nuget:?package=RA.Utilities.Feature&version=10.0.1
RA.Utilities.Feature
RA.Utilities.Feature provides a foundational toolkit for implementing the Vertical Slice Architecture pattern using CQRS (Command Query Responsibility Segregation).
It offers base handlers, validation behaviors, and exception handling mechanisms to streamline feature development and promote clean, maintainable code.
Building applications with a traditional layered architecture can lead to wide, coupled classes and scattered logic. The Vertical Slice pattern, combined with CQRS, addresses this by organizing code around features. This package provides the essential building blocks to support that pattern.
Getting started
dotnet add package RA.Utilities.Feature
🔗 Dependencies
RA.Utilities.Core.ExceptionsRA.Utilities.CoreFluentValidationMicrosoft.Extensions.DependencyInjection.AbstractionsMicrosoft.Extensions.Logging.Abstractions
✨ Features
1. Base Handlers
The package provides abstract base classes that implement the IRequestHandler interfaces.
Inheriting from these base classes gives your handlers a consistent structure and automatically handles cross-cutting concerns.
The primary base classes are:
RequestHandler<TRequest>: For handlers that process a request but do not return a value. It implementsIRequestHandler<TRequest>.RequestHandler<TRequest, TResponse>: The most common handler, for requests that return a value. It implementsIRequestHandler<TRequest, TResponse>and is designed to work with theResult<T>type fromRA.Utilities.Core.
These base classes include built-in logging for the start and end of a request, automatic exception catching (which wraps exceptions in a Result.Failure), and a clear HandleAsync method for you to override with your business logic.
2. Validation Pipeline Behavior
The ValidationBehavior<TRequest, TResponse> is a MediatR pipeline behavior that intercepts incoming requests, finds the corresponding FluentValidation validator, and executes it.
- If validation passes, the request proceeds to the handler.
- If validation fails, the pipeline is short-circuited, and a
Result.Failurecontaining aValidationExceptionis returned immediately. This prevents invalid data from ever reaching your business logic.
🚀 Usage Example
Let's walk through creating a complete feature slice for creating a new product.
Step 1: Define the Command and Validator
First, define the command (the request) and its validation rules.
// Features/Products/CreateProduct.cs
using FluentValidation;
using RA.Utilities.Core;
// The command containing the data for the new product
public record CreateProductCommand(string Name, decimal Price) : IRequest<Result<int>>;
// The validator for the command
public class CreateProductCommandValidator : AbstractValidator<CreateProductCommand>
{
public CreateProductCommandValidator()
{
RuleFor(x => x.Name).NotEmpty().MaximumLength(100);
RuleFor(x => x.Price).GreaterThan(0);
}
}
Step 2: Implement the Handler
Next, create the handler by inheriting from IRequestHandler<TRequest, TResponse>. This is where your business logic lives.
// Features/Products/CreateProduct.cs (continued)
using MediatR;
using RA.Utilities.Feature.Abstractions;
using Microsoft.Extensions.Logging;
using RA.Utilities.Core;
public class CreateProductHandler : RequestHandler<CreateProductCommand, Result<int>>
{
private readonly IProductRepository _productRepository;
// Inject dependencies and the base logger
public CreateProductHandler(IProductRepository productRepository, ILogger<CreateProductHandler> logger)
: base(logger)
{
_productRepository = productRepository;
}
// Override the base HandleAsync to implement the core business logic
public override async Task<Result<int>> HandleAsync(CreateProductCommand command, CancellationToken cancellationToken)
{
// Check if a product with the same name already exists
if (await _productRepository.DoesProductExistAsync(command.Name))
{
// Return a failure Result using a custom exception
return new ConflictException(nameof(Product), command.Name);
}
var newProduct = new Product { Name = command.Name, Price = command.Price };
var productId = await _productRepository.AddAsync(newProduct);
// Return a success Result with the new product's ID
return productId;
}
}
Step 3: Register Services in Program.cs
Finally, wire up MediatR, the validation behavior, and your validators in your application's service configuration.
// Program.cs
using RA.Utilities.Feature.Behaviors;
var builder = WebApplication.CreateBuilder(args);
_ = services.AddCustomMediator();
_ = services
.AddFeature<CreateProductCommand, CreateProductHandler>()
.AddDecoration<LoggingBehavior<CreateProductCommand>>()
.AddValidator<CreateProductCommandValidator>();
var app = builder.Build();
// ... your endpoint mapping
app.Run();
With this setup, when your API endpoint sends a CreateProductCommand, it will be automatically validated. If valid, the CreateProductHandler will execute within a managed scope that provides logging and exception safety.
Contributing
Contributions are welcome! If you have a suggestion or find a bug, please open an issue to discuss it.
Pull Request Process
- Fork the Repository: Start by forking the RA.Utilities repository.
- Create a Branch: Create a new branch for your feature or bug fix from the
mainbranch. - Make Your Changes: Write your code, ensuring it adheres to the existing coding style. Add or update XML documentation for any new public APIs.
- Update README: If you are adding new functionality, please update the
README.mdfile accordingly. - Submit a Pull Request: Push your branch to your fork and open a pull request to the
mainbranch of the original repository. Provide a clear description of the changes you have made.
Coding Standards
- Follow the existing coding style and conventions used in the project.
- Ensure all public members are documented with clear XML comments.
- Keep changes focused. A pull request should address a single feature or bug.
Thank you for contributing!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
- RA.Utilities.Application.Validation (>= 10.0.0)
- RA.Utilities.Core (>= 10.0.0)
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 |
|---|---|---|
| 10.0.1 | 58 | 1/12/2026 |
| 10.0.0 | 204 | 11/24/2025 |
| 10.0.0-rc.2 | 91 | 10/31/2025 |