Skip to main content

Using the PearDrop CLI

The PearDrop CLI scaffolds domain code and configures framework features. This guide covers domain scaffolding (aggregates, commands, queries, events).

Other CLI guides:

Installation

The CLI is pinned to a specific version in your project via .config/dotnet-tools.json.

Restore it:

dotnet tool restore

Verify:

dotnet tool run peardrop --version

Or add to PATH:

# Windows - run once
$env:PATH += ";$(dotnet tool list -g | grep peardrop | awk '{print $2}')"

# Then use directly
peardrop --help

Quick Reference

Add an Aggregate

peardrop add aggregate Equipment \
--properties "Name:string,IsAvailable:bool,Category:string"

Creates:

  • Infrastructure/Domain/EquipmentAggregate/AggregateRoot/EquipmentAggregate.cs
  • Infrastructure/Domain/EquipmentAggregate/ folder structure

Add a Command

# Simple command
peardrop add command CreateEquipment \
--aggregate Equipment \
--properties "Name:string,Category:string"

# Command with return type
peardrop add command ApproveCheckout \
--aggregate CheckoutRequest \
--properties "CheckoutId:Guid" \
--result CheckoutApprovedResult

Creates:

  • Infrastructure/Domain/EquipmentAggregate/Commands/CreateEquipmentCommand.cs
  • Infrastructure/Domain/EquipmentAggregate/CommandHandlers/CreateEquipmentCommandHandler.cs

Add a Query

# Query returning single item
peardrop add query GetEquipmentById \
--aggregate Equipment \
--properties "EquipmentId:Guid" \
--result EquipmentDetailDto

# Query returning list
peardrop add query ListEquipment \
--aggregate Equipment \
--result "List<EquipmentSummaryDto>"

Creates:

  • Queries/GetEquipmentByIdQuery.cs
  • Queries/QueryHandlers/GetEquipmentByIdQueryHandler.cs

Add an Integration Event

# Event with handler
peardrop add integration-event EquipmentCreated \
--aggregate Equipment \
--properties "EquipmentId:Guid,Name:string"

# Event without handler
peardrop add integration-event EquipmentDeleted \
--aggregate Equipment \
--no-handler

# Event with cross-library handler
peardrop add integration-event CheckoutRequested \
--aggregate Checkout \
--handler-project ../Notification.Module

Creates:

  • Infrastructure/Domain/EquipmentAggregate/IntegrationEvents/EquipmentCreatedIntegrationEvent.cs
  • Infrastructure/EventHandlers/EquipmentCreatedSubscriber.cs (if handler enabled)
  • Auto-updates Constants/{ProjectName}CapTopics.cs

Typical Feature Workflow

Step 1: Plan

Identify what you need:

  • Data to store (aggregate)
  • Operations that change it (commands)
  • Data users read (queries)
  • UI pages (components)

Example: Equipment Checkout System

  • Aggregate: Equipment, CheckoutRequest
  • Commands: CreateEquipment, RequestCheckout, ApproveCheckout, ReturnEquipment
  • Queries: GetEquipmentById, ListAvailableEquipment, ListMyCheckouts
  • Components: EquipmentList, EquipmentDetail, CheckoutForm, MyCheckouts

Step 2: Create Aggregates

# Create the aggregates
peardrop add aggregate Equipment \
--properties "Name:string,Description:string,Category:string,IsAvailable:bool"

peardrop add aggregate CheckoutRequest \
--properties "EquipmentId:Guid,UserId:Guid,RequestedDate:DateTime,Status:CheckoutStatus"

Now:

  • ✅ Open EquipmentAggregate.cs and add business logic
  • ✅ Open CheckoutRequestAggregate.cs and add validation rules
  • No need to create files manually!

Step 3: Create Commands

# Write side - what changes the data
peardrop add command CreateEquipment \
--aggregate Equipment \
--properties "Name:string,Description:string,Category:string"

peardrop add command RequestCheckout \
--aggregate CheckoutRequest \
--properties "EquipmentId:Guid,RequiredDate:DateTime"

peardrop add command ApproveCheckout \
--aggregate CheckoutRequest \
--properties "CheckoutRequestId:Guid"

peardrop add command ReturnEquipment \
--aggregate CheckoutRequest \
--properties "CheckoutRequestId:Guid"

Now:

  • ✅ Open each command handler
  • ✅ Implement validation logic
  • ✅ Call aggregate methods
  • ✅ Run migrations: dotnet ef migrations add CreateEquipmentAndCheckoutAggregates
  • ✅ Apply: peardrop migrate

Step 4: Create Queries

# Read side - what users view
peardrop add query GetEquipmentById \
--aggregate Equipment \
--properties "EquipmentId:Guid" \
--result EquipmentDetailDto

peardrop add query ListEquipment \
--aggregate Equipment \
--result "List<EquipmentSummaryDto>"

peardrop add query ListMyCheckouts \
--aggregate CheckoutRequest \
--result "List<MyCheckoutDto>"

Now:

  • ✅ Implement query handlers
  • ✅ Create read models for optimal queries
  • ✅ Add filters, pagination, etc.

Step 5: Create Components

# UI Components (not scaffolded by CLI)
# Create manually in Components/ folder

Reference: Project Structure

Step 6: Integration Events (Optional)

For cross-module communication:

peardrop add integration-event EquipmentCreated \
--aggregate Equipment \
--properties "EquipmentId:Guid,Name:string,Category:string"

peardrop add integration-event CheckoutApproved \
--aggregate CheckoutRequest \
--properties "CheckoutId:Guid,EquipmentId:Guid,UserId:Guid"

Property Types

Supported types in --properties:

TypeExample
stringName:string
intQuantity:int
longFileSize:long
decimalPrice:decimal
boolIsActive:bool
DateTimeCreatedAt:DateTime
DateOnlyDateRequested:DateOnly
GuidEquipmentId:Guid
EnumStatus:CheckoutStatus
List<T>Tags:List<string>

Options

OptionPurposeExample
--aggregateWhich aggregate--aggregate Equipment
--propertiesProperties to add--properties "Name:string,Count:int"
--resultQuery/Command return type--result EquipmentDetailDto
--no-handlerIntegration events only (no subscriber)--no-handler
--handler-projectCross-module event handler--handler-project ../Notification.Module

After Running CLI Commands

After the CLI generates files, you typically:

  1. Edit the aggregate - Add business logic and validation
  2. Edit the command handler - Add validation and domain logic
  3. Edit the query handler - Create read models and projections
  4. Create read models - For optimal query performance
  5. Run migrations - dotnet ef migrations add <Name>
  6. Update database - peardrop migrate

Example:

# 1. Generate
peardrop add command CreateEquipment --aggregate Equipment --properties "Name:string"

# 2. Edit handler file and add logic
# ... edit CreateEquipmentCommandHandler.cs ...

# 3. Create/update migrations
dotnet ef migrations add AddEquipment

# 4. Apply to DB
peardrop migrate

# 5. Test it!

Troubleshooting

"peardrop: command not found"

  • Run: dotnet tool restore
  • Or use: dotnet tool run peardrop

"Invalid property type"

"Aggregate not found"

  • Run: dotnet build first
  • Aggregate must exist before creating commands/queries

CLI generates wrong names

  • Check peardrop.json in project root
  • Verify projectName, appProject, clientProject

Best Practices

DO:

  • Plan aggregates first (don't randomly create)
  • Group related aggregates in bounded context folders
  • Run migrations after each aggregate
  • Name commands specifically (CreateEquipment not Update)
  • Use result types for commands (clear intent)

DON'T:

  • Create random properties you won't use
  • Skip implementing aggregate logic
  • Mix multiple aggregates in one command
  • Forget to run dotnet ef migrations add
  • Leave handlers empty (implement the logic!)

Next Steps