AlJawad.DefaultCQRS 1.0.8

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

AlJawad.DefaultCQRS

A powerful and scalable CQRS library for .NET applications.

Table of Contents

Introduction

AlJawad.DefaultCQRS is a .NET library that provides a ready-to-use implementation of the Command Query Responsibility Segregation (CQRS) pattern. It's designed to be highly generic and scalable, allowing you to quickly build robust and maintainable applications.

The library offers a set of default commands and queries for common CRUD operations, as well as support for caching, validation, and a unit of work. This allows you to focus on your business logic instead of writing boilerplate code.

Key Benefits

  • Reduce Boilerplate Code: The library provides a set of generic commands, queries, and handlers that can be used for any entity. This eliminates the need to write repetitive code for basic CRUD operations.
  • Scalability: By separating read and write operations, CQRS allows you to scale each side of your application independently. This library is designed to support this scalability.
  • Flexibility: The library is highly customizable. You can easily extend the default commands and queries or create your own to meet your specific needs.
  • Testability: The separation of concerns in CQRS makes it easier to test your application's business logic.
  • Getting Started

Getting Started

Installation

To install the library, you can use the .NET CLI:

dotnet add package AlJawad.DefaultCQRS

Configuration

Configuring the AlJawad.DefaultCQRS library involves two main steps: initializing the library's services and configuring your entities.

1. Initialize the Library

First, you need to call the InitializeDefaultCQRS extension method in your Program.cs file. This method sets up the necessary model binders for the library.

// In Program.cs

#region required for Default CQRS
builder.Services.InitializeDefaultCQRS();
#endregion
2. Configure Your Entities

For each entity you want to use with the library, you'll need to call the AddEntityDynamicConfiguration extension method. This method registers the default command and query handlers for your entity.

Here's an example of how to configure a Product entity:

// In Program.cs

#region required for Default CQRS
builder.Services.AddEntityDynamicConfiguration<Product, int, CreateProductDto, UpdateProductDto, ProductDto, ProductAuthorizationHandler>(builder.Configuration);
#endregion

In this example:

  • Product is the entity class.
  • int is the type of the entity's primary key.
  • CreateProductDto is the data transfer object (DTO) for creating a new product.
  • UpdateProductDto is the DTO for updating an existing product.
  • ProductDto is the DTO for reading a product.
  • ProductAuthorizationHandler is the authorization handler for the Product entity.

You will also need to configure the database connection string in your appsettings.json file.

Usage

Once you've configured the library, you can use the IMediator interface to send commands and queries.

Commands

The library provides a set of default commands for common CRUD operations.

Create

To create a new entity, you can send an EntityCreateCommand.

var command = new EntityCreateCommand<CreateProductDto, Response<ProductDto>>(createProductDto);
var response = await _mediator.Send(command);
Update

To update an existing entity, you can send an EntityUpdateCommand.

var command = new EntityUpdateCommand<int, UpdateProductDto, Response<ProductDto>>(productId, updateProductDto);
var response = await _mediator.Send(command);
Delete

To delete an entity, you can send an EntityDeleteCommand.

var command = new EntityDeleteCommand<int, Response<ProductDto>>(productId);
var response = await _mediator.Send(command);

Queries

The library also provides a set of default queries for reading data.

Get by ID

To retrieve an entity by its ID, you can send an EntityIdentifierQuery.

var query = new EntityIdentifierQuery<int, Response<ProductDto>>(productId);
var response = await _mediator.Send(query);
Get a List

To retrieve a list of entities, you can send an EntityListQuery.

var query = new EntityListQuery<ResponseArray<ProductDto>>();
var response = await _mediator.Send(query);
Get a Paged List

To retrieve a paged list of entities, you can send an EntityPagedQuery.

var query = new EntityPagedQuery<ResponseList<ProductDto>>(pageNumber, pageSize);
var response = await _mediator.Send(query);

Advanced Topics

Validation

The library uses FluentValidation to validate commands. This is handled by the ValidateEntityModelCommandBehavior, which is automatically registered when you configure your entities.

You can create validators for your command DTOs, and they will be automatically applied. For example, to create a validator for the CreateProductDto, you would create a class that inherits from BaseValidator<CreateProductDto, Product, long, ProductDto>.

Here's an example of a validator for the CreateProductDto:

public class ProductCreateValidator : BaseValidator<CreateProductDto, Product, long, ProductDto>
{
    public ProductCreateValidator(IUnitOfWork unitOfWork, IDistributedCache cache)
        : base(unitOfWork, cache)
    {
        var _repository = unitOfWork.Set<Product>();

        RuleFor(x => x.Name).NotNull().NotEmpty().WithMessage("Required");
        RuleFor(x => x.Price).NotNull().WithMessage("Required");
        RuleFor(e => e).Custom((p, context) =>
        {
            var alreadyExist = _repository.FirstOrDefault(x => x.Name == p.Name);
            if (alreadyExist != null)
            {
                context.AddFailure(new ValidationFailure("Name", "Already Existed"));
            }
        });
    }
}

Unit of Work

The library uses the Unit of Work pattern to ensure that all database operations within a single command are transactional. The UnitOfWork class is automatically registered with the dependency injection container and can be injected into your command handlers.

Custom Handlers

If you need to implement custom logic for a specific command, you can create your own handler by inheriting from one of the default handler classes. For example, to create a custom handler for the EntityCreateCommand, you would create a class that inherits from EntityCreateCommandHandler.

Here's an example of a custom handler for creating a Category entity:

public class CategoryCreateCommandHandler : EntityCreateCommandHandler<IUnitOfWork, Category, int, CreateCategoryDto, CategoryDto>
{
    public CategoryCreateCommandHandler(ILoggerFactory loggerFactory,
        IUnitOfWork dataContext,
        IMapper mapper,
        IHttpContextAccessor context,
        IDistributedCache cache,
        IServiceProvider provider)
        : base(loggerFactory, dataContext, mapper, context, cache, provider)
    {
    }

    protected override async Task<Response<CategoryDto>> ProcessAsync(EntityCreateCommand<CreateCategoryDto, Response<CategoryDto>> request, CancellationToken cancellationToken)
    {
        // Implement your custom logic here.
        // For example, you can add additional validation, logging, or other business logic.

        return await base.ProcessAsync(request, cancellationToken);
    }
}

Once you've created your custom handler, you need to configure it in your Program.cs file using the WithCreateHandler method:

builder.Services.AddEntityDynamicConfiguration<Category, int, CreateCategoryDto, UpdateCategoryDto, CategoryDto, CategoryAuthorizationHandler>(builder.Configuration)
    .WithCreateHandler<CategoryCreateCommandHandler>()
	.SkipUpdateValidator(false);//TO skip the validation 
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
1.0.8 53 3/22/2026
1.0.7 443 11/18/2025
1.0.6 189 11/15/2025
1.0.5 174 11/8/2025
1.0.4 146 11/7/2025
1.0.3 143 11/7/2025
1.0.2 204 9/25/2025
1.0.1 278 9/24/2025
1.0.0 261 9/21/2025