Skip to content
Development
Agent

cqrs-generator

Generates CQRS Commands, Queries, and Handlers using MediatR

From plugin
f5-framework
24104 skills104 agents69 commands

Claude Code

> /plugin marketplace add Fujigo-Software/f5-framework-claude

Agent definition

cqrs-generator.md
name: dotnet-cqrs-generator
description: Generates CQRS Commands, Queries, and Handlers using MediatR
triggers:
  - create command
  - create query
  - generate handler
  - cqrs
  - mediatr

CQRS/MediatR Generator

Purpose

Generate Commands, Queries, and Handlers following CQRS pattern with MediatR for clean separation of read and write operations.

Required Context

Before generating, gather: 1. **Operation Type**: Command (write) or Query (read) 2. **Entity Name**: Target entity 3. **Action**: Specific operation (Create, Update, Delete, Get, List) 4. **Parameters**: Required input data

Command Generation Template

Create Command

// {{SolutionName}}.Application/{{EntityName}}s/Commands/Create{{EntityName}}/Create{{EntityName}}Command.cs
using MediatR;
using {{SolutionName}}.Application.DTOs;

namespace {{SolutionName}}.Application.{{EntityName}}s.Commands.Create{{EntityName}};

public record Create{{EntityName}}Command(
    string Name,
    string? Description,
    decimal Price,
    Guid CategoryId
) : IRequest<{{EntityName}}Dto>;

Command Handler

// {{SolutionName}}.Application/{{EntityName}}s/Commands/Create{{EntityName}}/Create{{EntityName}}CommandHandler.cs
using AutoMapper;
using MediatR;
using {{SolutionName}}.Application.DTOs;
using {{SolutionName}}.Domain.Entities;
using {{SolutionName}}.Domain.Interfaces;

namespace {{SolutionName}}.Application.{{EntityName}}s.Commands.Create{{EntityName}};

public class Create{{EntityName}}CommandHandler
    : IRequestHandler<Create{{EntityName}}Command, {{EntityName}}Dto>
{
    private readonly I{{EntityName}}Repository _repository;
    private readonly IUnitOfWork _unitOfWork;
    private readonly IMapper _mapper;

    public Create{{EntityName}}CommandHandler(
        I{{EntityName}}Repository repository,
        IUnitOfWork unitOfWork,
        IMapper mapper)
    {
        _repository = repository;
        _unitOfWork = unitOfWork;
        _mapper = mapper;
    }

    public async Task<{{EntityName}}Dto> Handle(
        Create{{EntityName}}Command request,
        CancellationToken cancellationToken)
    {
        var entity = {{EntityName}}.Create(
            request.Name,
            request.Description,
            request.Price,
            request.CategoryId);

        await _repository.AddAsync(entity, cancellationToken);
        await _unitOfWork.SaveChangesAsync(cancellationToken);

        return _mapper.Map<{{EntityName}}Dto>(entity);
    }
}

Command Validator

// {{SolutionName}}.Application/{{EntityName}}s/Commands/Create{{EntityName}}/Create{{EntityName}}CommandValidator.cs
using FluentValidation;

namespace {{SolutionName}}.Application.{{EntityName}}s.Commands.Create{{EntityName}};

public class Create{{EntityName}}CommandValidator
    : AbstractValidator<Create{{EntityName}}Command>
{
    public Create{{EntityName}}CommandValidator()
    {
        RuleFor(x => x.Name)
            .NotEmpty()
            .MaximumLength(200);

        RuleFor(x => x.Description)
            .MaximumLength(1000);

        RuleFor(x => x.Price)
            .GreaterThanOrEqualTo(0);

        RuleFor(x => x.CategoryId)
            .NotEmpty();
    }
}

Query Generation Template

Get Query

// {{SolutionName}}.Application/{{EntityName}}s/Queries/Get{{EntityName}}ById/Get{{EntityName}}ByIdQuery.cs
using MediatR;
using {{SolutionName}}.Application.DTOs;

namespace {{SolutionName}}.Application.{{EntityName}}s.Queries.Get{{EntityName}}ById;

public record Get{{EntityName}}ByIdQuery(Guid Id) : IRequest<{{EntityName}}Dto?>;

Query Handler

// {{SolutionName}}.Application/{{EntityName}}s/Queries/Get{{EntityName}}ById/Get{{EntityName}}ByIdQueryHandler.cs
using AutoMapper;
using MediatR;
using {{SolutionName}}.Application.DTOs;
using {{SolutionName}}.Domain.Interfaces;

namespace {{SolutionName}}.Application.{{EntityName}}s.Queries.Get{{EntityName}}ById;

public class Get{{EntityName}}ByIdQueryHandler
    : IRequestHandler<Get{{EntityName}}ByIdQuery, {{EntityName}}Dto?>
{
    private readonly I{{EntityName}}Repository _repository;
    private readonly IMapper _mapper;

    public Get{{EntityName}}ByIdQueryHandler(
        I{{EntityName}}Repository repository,
        IMapper mapper)
    {
        _repository = repository;
        _mapper = mapper;
    }

    public async Task<{{EntityName}}Dto?> Handle(
        Get{{EntityName}}ByIdQuery request,
        CancellationToken cancellationToken)
    {
        var entity = await _repository.GetByIdAsync(
            request.Id,
            cancellationToken);

        return entity is null
            ? null
            : _mapper.Map<{{EntityName}}Dto>(entity);
    }
}

List Query with Pagination

// Get{{EntityName}}sQuery.cs
public record Get{{EntityName}}sQuery(
    string? SearchTerm,
    int PageNumber = 1,
    int PageSize = 10
) : IRequest<PaginatedList<{{EntityName}}Dto>>;

// Get{{EntityName}}sQueryHandler.cs
public class Get{{EntityName}}sQueryHandler
    : IRequestHandler<Get{{EntityName}}sQuery, PaginatedList<{{EntityName}}Dto>>
{
    public async Task<PaginatedList<{{EntityName}}Dto>> Handle(
        Get{{EntityName}}sQuery request,
        CancellationToken cancellationToken)
    {
        var query = _repository.Query();

        if (!string.IsNullOrEmpty(request.SearchTerm))
        {
            query = query.Where(x =>
                x.Name.Contains(request.SearchTerm));
        }

        return await query
            .ProjectTo<{{EntityName}}Dto>(_mapper.ConfigurationProvider)
            .ToPaginatedListAsync(
                request.PageNumber,
                request.PageSize,
                cancellationToken);
    }
}

Pipeline Behaviors

Validation Behavior

// {{SolutionName}}.Application/Common/Behaviors/ValidationBehavior.cs
using FluentValidation;
using MediatR;

public class ValidationBehavior<TRequest, TResponse>
    : IPipelineB
Read more
@fujigo-software
Ships withf5-framework

AI-Powered Development Framework for Claude Code

2434 skills104 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
24
Star history of Fujigo-Software/f5-framework-claude on GitHub, a chart by star-history.com

Other agents on f5-framework.

More agents from other plugins.

a11y-architect
Auto-invoked

a11y-architect

Agent

Accessibility Architect specializing in WCAG 2.2 compliance for Web and Native platforms. Use PROACTIVELY when designing UI…

ecc2w293k
@affaan-m@affaan-mInstall Agent
analyze-pass-impact

analyze-pass-impact

Agent

Analyzes how a specific topic affects a group of compiler passes. Used by the /plan-update skill to parallelize research across…

react4d252k
@facebook@facebookInstall Agent
orchestrator

orchestrator

Agent

- If the user makes a simple request (such as asking for the time) which you can fulfill by running a terminal command (such as…

codex3d135k
@openai@openaiInstall Agent
cavecrew-builder

cavecrew-builder

Agent

Surgical 1-2 file edit. Typo fixes, single-function rewrites, mechanical renames, comment removal, format-preserving tweaks. Hard…

caveman4d119k
@juliusbrussee@juliusbrusseeInstall Agent

Questions about cqrs-generator.

Which coding agents can use cqrs-generator?
cqrs-generator installs in Claude Code and Cursor: each loads subagents from .claude/agents, so copy the file there. Flowy's auto-invocation runs in Claude Code only.