RA.Utilities.Feature
The main goal of this package is to help you organize your application's business logic into self-contained "features" or "slices." Instead of having logic for a single operation scattered across multiple layers (e.g., a controller, a service, a repository), all the code for one use case—from the incoming request to the final response—is located together.
This solves a common problem with traditional layered architectures where classes can become bloated and tightly coupled, making the codebase difficult to navigate and maintain.
✨ Key Features and How They Help
The package provides several key components to achieve this clean architecture:
- Base Handlers (
IRequestHandler<TRequest, TResponse>):
- *Purpose: These are base classes for your CQRS command and query handlers.
- Benefit: They reduce boilerplate code by providing built-in logging for the start and end of a request, as well as automatic exception handling. Any unhandled exception within your logic is safely caught and wrapped in a Result.Failure object, preventing crashes and ensuring a consistent error-handling strategy.
- Validation Pipeline Behavior (
ValidationBehavior<TRequest, TResponse>):
- Purpose: This is a pipeline behavior (like MediatR middleware) that automatically validates incoming commands and queries before they reach your business logic.
- Benefit: It uses
FluentValidationto check the request. If validation fails, it immediately stops processing and returns a structured validation error. This ensures that your handlers only ever deal with valid data, making them simpler and more robust.
- Seamless Integration with RA.Utilities.Core:
- Purpose: The handlers are designed to return a
Result<T>object from theRA.Utilities.Corepackage. - Benefit: This allows you to explicitly communicate the outcome of an operation—either success with a value or a predictable failure (like "user not found" or "item already exists")—without using exceptions for control flow. This leads to cleaner, more readable, and more predictable code.
🌟 Benefits
The package has been fully rewritten to avoid reflection, it uses strongly-typed generic registration and explicit DI resolution instead of dynamic type lookups or assembly scanning.
- ✅ No runtime reflection
- ✅ Purely generic and compile-time safe
- ✅ Simplified DI registration via
AddRequestHandler<TRequest, TResponse, THandler>() - ✅ The mediator now supports notifications and publish/subscribe just like MediatR.
- ✅ Multiple notifications (publish/subscribe model)
- ✅ Multiple notification pipeline behaviors (logging, metrics, retry, etc.)
- ✅ Fluent builder style consistent with the request builder
🔧 Design Overview
IFeatureBuilder→ Fluent builder interfaceFeatureBuilder<TRequest, TResponse>andFeatureBuilder<TRequest>→ Concrete builders for both request types- Extension methods:
AddFeature<TRequest, TResponse, THandler>()AddFeature<TRequest, THandler>()
- Each builder:
- Registers the handler.
- Supports
.AddDecoration<TBehavior>()→ registers a pipeline behavior. - Supports
.AddValidator<TValidator>()→ registers validation pipeline.
🛠️ Installation
You can install the package via the .NET CLI:
dotnet add package RA.Utilities.Feature
Or through the NuGet Package Manager console:
Install-Package RA.Utilities.Feature
🔗 Dependencies
RA.Utilities.Core.ExceptionsRA.Utilities.CoreFluentValidationMicrosoft.Extensions.DependencyInjection.AbstractionsMicrosoft.Extensions.Logging.Abstractions
🗃️ RA.Utilities.Feature.Abstractions
8 items
🗃️ RA.Utilities.Feature.Behaviors
5 items
🗃️ RA.Utilities.Feature.Models
2 items
🗃️ RA.Utilities.Feature.Extensions
2 items