Skip to main content

Project Templates

Get started quickly with dotnet new templates for Excalibur projects.

Before You Start

  • .NET 8.0+ (or .NET 9/10 for latest features)
  • Install the template pack:
    dotnet new install Excalibur.Templates

Available Templates

TemplateShort NameDescriptionKey Options
Dispatch APIdispatch-apiASP.NET Core API with Dispatch messaging--Transport, --IncludeDocker, --IncludeTests
Dispatch Workerdispatch-workerBackground worker with message processing--Transport, --IncludeDocker, --IncludeTests
Excalibur DDDexcalibur-dddDomain-Driven Design with Event Sourcing--Database, --IncludeDocker, --IncludeTests
Excalibur CQRSexcalibur-cqrsFull CQRS pattern with event sourcing--Transport, --Database, --IncludeDocker, --IncludeTests

Installation

Install the templates package:

dotnet new install Excalibur.Dispatch.Templates

Verify installation:

dotnet new list dispatch

Using Templates

Dispatch API

Create a new API project with Dispatch messaging:

dotnet new dispatch-api -n MyApi
cd MyApi
dotnet run

What's included:

  • ASP.NET Core Web API with controllers
  • Dispatch registration via AddDispatch() unified builder
  • Sample CreateOrderAction / GetOrderAction with working handler implementations
  • InMemoryOrderStore demonstrating a replaceable persistence pattern
  • Transport selection via --Transport option
  • appsettings.json with transport configuration
# With Kafka transport and tests
dotnet new dispatch-api -n MyApi --Transport kafka --IncludeTests

# With Docker support
dotnet new dispatch-api -n MyApi --Transport rabbitmq --IncludeDocker

Dispatch Worker

Create a background worker service:

dotnet new dispatch-worker -n MyWorker

What's included:

  • .NET Worker Service with Host.CreateDefaultBuilder
  • OrderProcessingWorker background service
  • Sample OrderCreatedEventHandler
  • Transport selection via --Transport option
# With RabbitMQ and tests
dotnet new dispatch-worker -n MyWorker --Transport rabbitmq --IncludeTests

Excalibur DDD

Create a Domain-Driven Design project with Event Sourcing:

dotnet new excalibur-ddd -n MyDomain

What's included:

  • Domain layer with Order aggregate using pattern matching (no reflection)
  • Domain events: OrderCreated, OrderShipped
  • Value objects: Money
  • Application layer: CreateOrderCommand, GetOrderQuery with handlers
  • Event sourcing via AddExcalibur() unified builder
  • Database selection via --Database option
# With PostgreSQL and tests
dotnet new excalibur-ddd -n MyDomain --Database postgresql --IncludeTests

Excalibur CQRS

Create a full CQRS implementation:

dotnet new excalibur-cqrs -n MyCqrs

What's included:

  • Command and query separation with working handler implementations
  • Dispatch for command/query handling via AddDispatch()
  • Excalibur for event sourcing via AddExcalibur()
  • Read model projections: OrderReadModel, OrderProjection with real upsert logic
  • InMemoryProjectionStore<T> implementing IProjectionStore<T> for demonstration
  • Combined transport + database selection
# Full CQRS with Kafka transport and PostgreSQL
dotnet new excalibur-cqrs -n MyCqrs --Transport kafka --Database postgresql --IncludeTests --IncludeDocker

Template Options

Common Options (All Templates)

OptionTypeDefaultDescription
--Frameworkchoicenet8.0Target framework (net8.0, net9.0)
--IncludeDockerboolfalseInclude Dockerfile and .dockerignore
--IncludeTestsboolfalseInclude test project (xUnit + Shouldly + FakeItEasy)

Transport Options (dispatch-api, dispatch-worker, excalibur-cqrs)

OptionDescription
inmemoryIn-memory transport (default, for development)
kafkaApache Kafka transport
rabbitmqRabbitMQ transport
azureservicebusAzure Service Bus transport
awssqsAWS SQS transport
dotnet new dispatch-api -n MyApi --Transport kafka

Database Options (excalibur-ddd, excalibur-cqrs)

OptionDescription
sqlserverSQL Server (default)
postgresqlPostgreSQL
inmemoryIn-memory (for testing)
dotnet new excalibur-ddd -n MyDomain --Database postgresql

NuGet Package Versions

Templates reference Excalibur packages via a configurable MSBuild property:

<PropertyGroup>
<ExcaliburDispatchVersion>0.1.0-*</ExcaliburDispatchVersion>
</PropertyGroup>

Override at build time or in Directory.Build.props:

dotnet build -p:ExcaliburDispatchVersion=1.0.0

Template Structure

dispatch-api

MyApi/
├── Controllers/
│ └── OrdersController.cs
├── Actions/
│ ├── CreateOrderAction.cs
│ └── GetOrderAction.cs
├── Handlers/
│ ├── CreateOrderHandler.cs
│ └── GetOrderHandler.cs
├── Infrastructure/
│ └── InMemoryOrderStore.cs
├── Program.cs
├── appsettings.json
├── MyApi.csproj
├── Dockerfile (--IncludeDocker)
├── .dockerignore (--IncludeDocker)
└── MyApi.Tests/ (--IncludeTests)
├── Handlers/
│ └── CreateOrderHandlerShould.cs
└── MyApi.Tests.csproj

dispatch-worker

MyWorker/
├── Workers/
│ └── OrderProcessingWorker.cs
├── Handlers/
│ └── OrderCreatedEventHandler.cs
├── Program.cs
├── appsettings.json
├── MyWorker.csproj
├── Dockerfile (--IncludeDocker)
├── .dockerignore (--IncludeDocker)
└── MyWorker.Tests/ (--IncludeTests)
├── Handlers/
│ └── OrderCreatedEventHandlerShould.cs
└── MyWorker.Tests.csproj

excalibur-ddd

MyDomain/
├── Domain/
│ ├── Aggregates/
│ │ └── Order.cs
│ ├── Events/
│ │ ├── OrderCreated.cs
│ │ └── OrderShipped.cs
│ └── ValueObjects/
│ └── Money.cs
├── Application/
│ ├── Commands/
│ │ ├── CreateOrderCommand.cs
│ │ └── CreateOrderCommandHandler.cs
│ └── Queries/
│ ├── GetOrderQuery.cs
│ └── GetOrderQueryHandler.cs
├── Program.cs
├── appsettings.json
├── MyDomain.csproj
├── Dockerfile (--IncludeDocker)
├── .dockerignore (--IncludeDocker)
└── MyDomain.Tests/ (--IncludeTests)
├── Domain/
│ └── OrderShould.cs
└── MyDomain.Tests.csproj

excalibur-cqrs

MyCqrs/
├── Domain/
│ ├── Aggregates/
│ │ └── Order.cs
│ └── Events/
│ ├── OrderCreated.cs
│ └── OrderShipped.cs
├── Application/
│ ├── Commands/
│ │ ├── CreateOrderCommand.cs
│ │ └── CreateOrderCommandHandler.cs
│ └── Queries/
│ ├── GetOrderQuery.cs
│ └── GetOrderQueryHandler.cs
├── Infrastructure/
│ └── InMemoryProjectionStore.cs
├── ReadModel/
│ ├── OrderReadModel.cs
│ └── OrderProjection.cs
├── Program.cs
├── appsettings.json
├── MyCqrs.csproj
├── Dockerfile (--IncludeDocker)
├── .dockerignore (--IncludeDocker)
└── MyCqrs.Tests/ (--IncludeTests)
├── Domain/
│ └── OrderShould.cs
└── MyCqrs.Tests.csproj

Generated Code Patterns

Unified Builder (All Templates)

All templates use the unified builder patterns from Sprints 499-502:

// Dispatch API / Worker
builder.Services.AddDispatch(dispatch =>
{
dispatch.AddHandlersFromAssembly(typeof(Program).Assembly);
// Transport added based on --Transport option
});

// Excalibur DDD / CQRS
builder.Services.AddExcalibur(excalibur =>
{
excalibur.AddEventSourcing(es =>
{
// Database configured based on --Database option
});
});

Pattern Matching in Aggregates

The excalibur-ddd and excalibur-cqrs templates demonstrate the correct event application pattern using switch expressions (no reflection):

protected override void ApplyEventInternal(IDomainEvent @event) => _ = @event switch
{
OrderCreated e => Apply(e),
OrderShipped e => Apply(e),
_ => throw new InvalidOperationException($"Unknown event: {@event.GetType().Name}")
};

Dockerfile Framework Tags

When using --IncludeDocker, the generated Dockerfile automatically uses the correct .NET base image tag matching your --Framework selection:

# net8.0 → Dockerfile uses sdk:8.0 and aspnet:8.0
dotnet new dispatch-api -n MyApi --Framework net8.0 --IncludeDocker

# net9.0 → Dockerfile uses sdk:9.0 and aspnet:9.0
dotnet new dispatch-api -n MyApi --Framework net9.0 --IncludeDocker

Worker templates use runtime: instead of aspnet: for the final stage image.

Updating Templates

Update to the latest version:

dotnet new update

Or reinstall:

dotnet new install Excalibur.Dispatch.Templates --force

Uninstalling Templates

Remove the templates:

dotnet new uninstall Excalibur.Dispatch.Templates

Creating Custom Templates

Create your own templates based on your organization's standards:

  1. Create a template.json configuration
  2. Package as a NuGet package
  3. Install locally or publish to a feed

See Microsoft's template authoring guide for details.

What's Next

See Also

  • Getting Started — Install Dispatch and create your first message handler in 5 minutes
  • Configuration — Configure Dispatch options, transports, and middleware via code or appsettings
  • ASP.NET Core Deployment — Deploy Dispatch applications in ASP.NET Core hosting environments