MMCA.Templates 1.4.0

Prefix Reserved
dotnet new install MMCA.Templates@1.4.0
                    
This package contains a .NET Template Package you can call from the shell/command line.

MMCA.Templates

dotnet new templates for the MMCA.Common framework: .NET 10, DDD, Clean Architecture, and CQRS, built as a modular monolith you can extract services out of later without a rewrite.

dotnet new install MMCA.Templates
dotnet new mmca-app -n Contoso.Support --module Orders --aggregate Order
cd Contoso.Support
dotnet build Contoso.Support.slnx
dotnet test  --solution Contoso.Support.slnx

That generates a warning-free, test-passing, migration-ready solution: one business module across all five layers, a REST API host, a Blazor Server + MudBlazor UI host, an Aspire AppHost, a per-database migrations project, and domain, application, and architecture-fitness test projects.

Templates

Short name Generates
mmca-app the whole solution: build plumbing, one module, both hosts, the AppHost, migrations, tests
mmca-module a new business module across all five layers, plus its test and migrations projects
mmca-command one write-side vertical slice inside an existing module: command record + handler
mmca-query one read-side vertical slice inside an existing module: cacheable query record + handler

mmca-app parameters

Parameter Default Meaning
-n, --name MMCA.App solution and root namespace, for example Contoso.Support
-m, --module Tickets the first business module, plural PascalCase
-a, --aggregate Ticket that module's aggregate root, singular PascalCase
-c, --child Comment the aggregate's child entity, singular PascalCase; the type is <aggregate><child>, so --aggregate Order --child Item gives OrderItem, AddItem / EditItem / RemoveItem slices, and /items routes
--title Title the aggregate's main text property; error codes, the max-length constant, the DTO and request properties, the EF column, the validator rule, the UI field and column resources, and the domain tests all follow
--event-verb Opened verb of the creation integration event, past tense; --aggregate Order --event-verb Placed gives OrderPlacedIntegrationEvent and its OrderPlacedHandler consumer
--flat off generate no child collection at all: no child entity, DTO, requests, mapper, EF configuration, Add/Edit/Remove slices, endpoints, alias, or tests (makes --child irrelevant)
--no-status off generate no status axis: no status enum, no ChangeStatus slice, request, or endpoint, no Status property, no status invariant or tests
--no-description off generate no long-text property: no Description property or invariant, no max-length constant, no DTO, request, or command field, no validator rule, no EF max-length configuration, no error-resource entries, no UI field, no tests
--no-owner off generate no owning-user property: no RequesterUserId property, no create-request field or validator rule, no member on the creation integration event, no EF index, no UI field or column, no tests
-f, --framework-version the version this pack was built against the MMCA.Common.* version to pin (all packages move together)
--local-mmca off build against ../MMCA.Common/Source instead of the published packages
--no-restore off skip the restore after generation

--flat, --no-status, --no-description and --no-owner are shape decisions, not toggles: the code for an axis you turn off is never generated, so there is nothing to delete afterwards. Passing any of the four also drops the sample migrations, because they describe the full shape; run dotnet ef migrations add InitialCreate against the shape you asked for. Plural forms are derived by a simple English pluralizer (ItemItems, EntryEntries, BoxBoxes), so an irregular noun needs one rename by hand.

Two shapes worth naming, because they are what most adopters reach for first:

dotnet new mmca-app -n Contoso.Catalog --module Products --aggregate Product \
  --flat --no-status --no-owner --title Name
dotnet new mmca-app -n Zeta.Orders --module Orders --aggregate Order --child Item \
  --no-owner --no-description --title CustomerName --event-verb Placed

--title and --event-verb are plain renames rather than shape decisions, and both are substring replacements: a multi-word --title CustomerName reaches the two shipped error messages as well as the identifiers, so "Ticket title cannot be empty." arrives as "Order customerName cannot be empty." Identifiers have to compile; those two strings are a one-line edit in the module's error resources after generating.

Adding a module to a generated solution

mmca-app ships build/add-module.ps1 inside every solution it generates, and that is the supported way to add the second module. It runs mmca-module for you and then performs all seven wire-ups the template can only print, plus the first EF migration:

pwsh build/add-module.ps1 -Name Orders -Aggregate Order -Child Item -EventVerb Placed
Parameter Maps to Meaning
-Name -n the module, plural PascalCase
-Aggregate --aggregate the module's aggregate root, singular PascalCase
-Child --child rename the child entity
-Title --title rename the aggregate's main text property
-EventVerb --event-verb verb of the creation integration event
-Flat --flat no child collection
-NoStatus --no-status no status axis
-NoOwner --no-owner no owning-user property
-NoDescription --no-description no long-text property
-SkipMigration print the dotnet ef migrations add command instead of running it

It must be run from the solution root, and it discovers everything else there: the solution file (which is also the app's root namespace), the module already present, and the web host, AppHost and architecture-test projects, all by glob. Nothing about the app that generated it is baked in, which is why the file is declared copyOnly in mmca-app's template.json: it ships verbatim, with no token replacement, so the flag names it passes through survive whatever --title / --event-verb / --child values the solution was generated with. build/templates/stage.ps1 guards both halves of that (the declaration, and that the script names none of the seed's own types or paths).

Every edit is anchored, a missing anchor aborts the run with the manual edit printed instead, a name already under Source/Modules is refused before anything is generated, and each already-applied step is skipped rather than duplicated. build/templates/smoke.ps1 adds its second module through this script, so the wire-ups are covered by the same code path adopters run.

mmca-module parameters

Run this from your solution root. It prints the seven wire-ups it cannot perform for you (a solution generated by mmca-app should use build/add-module.ps1 above instead, which performs them).

Parameter Default Meaning
-n, --name Sample the module, plural PascalCase; names the folders, projects, and namespaces
--app required your solution / root namespace
-a, --aggregate required the module's aggregate root, singular PascalCase
-c, --child Comment the aggregate's child entity, as above
--title Title the aggregate's main text property, as above
--event-verb Opened verb of the creation integration event, as above
--flat off as above
--no-status off as above
--no-description off as above
--no-owner off as above

mmca-command and mmca-query parameters

Run these from an existing module's UseCases folder.

Parameter Applies to Default Meaning
-n, --name both the use case, PascalCase; names the folder, the namespace, and both types
--app both required your solution / root namespace
-m, --module both required the module the slice goes into
-a, --aggregate both required the aggregate the handler loads
--domain-method mmca-command Delete the guarded method the command calls on the aggregate
--child-collection both unset navigation to eager-load, for example Lines; unset loads the aggregate root alone

--domain-method is the one thing the scaffold cannot invent. Add that method to your aggregate returning Result before the slice compiles, or you get 'Order' does not contain a definition for 'Cancel'.

Full reference: https://ivanball.github.io/docs/guides/common-TEMPLATES.html. Getting started (six steps to a running app): https://ivanball.github.io/docs/guides/common-GETTING-STARTED.html. What the generated code does, phase by phase: https://ivanball.github.io/docs/guides/common-BUILD-BY-HAND.html.

How this package is built

The template content is the MMCA.Helpdesk reference application itself, staged at pack time. There is no second copy of the solution, so the template cannot drift from the app whose CI keeps it building.

This package has no dependencies.

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.4.0 98 8/6/2026
1.3.0 87 8/6/2026
1.2.0 92 8/5/2026
1.1.0 104 8/4/2026
1.0.1 111 8/3/2026
1.0.0 110 8/2/2026