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
                    
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="RA.Utilities.Feature" Version="10.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RA.Utilities.Feature" Version="10.0.1" />
                    
Directory.Packages.props
<PackageReference Include="RA.Utilities.Feature" />
                    
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 RA.Utilities.Feature --version 10.0.1
                    
#r "nuget: RA.Utilities.Feature, 10.0.1"
                    
#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 RA.Utilities.Feature@10.0.1
                    
#: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=RA.Utilities.Feature&version=10.0.1
                    
Install as a Cake Addin
#tool nuget:?package=RA.Utilities.Feature&version=10.0.1
                    
Install as a Cake Tool

RA.Utilities.Feature

NuGet version Codecov NuGet Downloads Documentation GitHub license

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


✨ 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 implements IRequestHandler<TRequest>.
  • RequestHandler<TRequest, TResponse>: The most common handler, for requests that return a value. It implements IRequestHandler<TRequest, TResponse> and is designed to work with the Result<T> type from RA.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.Failure containing a ValidationException is 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

  1. Fork the Repository: Start by forking the RA.Utilities repository.
  2. Create a Branch: Create a new branch for your feature or bug fix from the main branch.
  3. Make Your Changes: Write your code, ensuring it adheres to the existing coding style. Add or update XML documentation for any new public APIs.
  4. Update README: If you are adding new functionality, please update the README.md file accordingly.
  5. Submit a Pull Request: Push your branch to your fork and open a pull request to the main branch 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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