Skip to content
bitzorcas
中EN

Tutorial

Create and Run a Consumer Solution

Use default-business-multi to install the template, generate a project, verify composition, restore commercial packages, run Aspire, and accept the starter slice.

Last updated

This tutorial creates Acme.ServiceDesk: multi-tenant, Aspire-orchestrated, SqlSugar, with no optional Platform module or industry extension. Output includes API, ServiceDefaults, AppHost, Business Starter Contracts/Application, Unit Tests, Architecture Tests, and composition evidence.

[!NOTE] For new projects, prefer the bitz scaffolder: bitz new offers scenario presets, orthogonal dimension composition, SqlSugar and EF Core persistence ORM adapters, and bitz add/remove module for existing solutions. This page keeps the dotnet new bitzorcas-host template-matrix tutorial; both channels share the same verified consumer baseline, and retirement conditions are tracked in 0004-template-upgrade-map.json.

The neutral Profile keeps the first-success path focused. Authorization, MasterData, and industry variants add their own packages, configuration, and tests on the same base topology and should be adopted separately after this path works.

Target topology

Acme.ServiceDesk.AppHost

SQL Server
PrimaryDatabase

schema-migrator
--migrate-schema apply

Acme.ServiceDesk.Api

Business Starter
WorkItem vertical slice

Commercial Profile
Default.Business + SqlSugar

Unit + Architecture Tests

AppHost waits for the database, then for a successful one-shot schema-migrator, and only then starts API. A schema failure must keep API stopped.

1. Check the environment and Feed

Terminal window
dotnet --version
dotnet nuget list source
test -n "$BITZORCAS_COMMERCIAL_FEED_URL"

SDK resolution should follow the repository’s 10.0.302 / latestFeature policy. Use the source key BitzOrcasCommercial; supply credentials through a Credential Provider or CI secret. See Prerequisites.

2. Install and inspect the contract

Terminal window
dotnet new install BitzOrcas.Modern.Templates@1.0.0-alpha1
dotnet new bitzorcas-host --help

Help should expose ProfileChoice and RuntimeAdapter, including default-business-multi and sqlsugar. If other business selectors appear, verify the installed version before generation.

3. Generate into an empty directory

Terminal window
# Select Multi Business, Aspire topology, and the SqlSugar provider in one command.
dotnet new bitzorcas-host \
--name Acme.ServiceDesk \
--output ./Acme.ServiceDesk \
--ProfileChoice default-business-multi \
--RuntimeAdapter sqlsugar
cd Acme.ServiceDesk

Command completion means native template files have been generated; there is no later materialization stage. Customer output must contain no tools/, Python file, or foundation Framework/Platform source.

The terminal below shows steps 2–4 as actually run (install confirmation, generation, manifest/plan verification; CLI output stays in the tool’s localized form):

bitzorcas-host session
$ 
成功: BitzOrcas.Modern.Templates@1.0.0-alpha1 已安装以下模板:
模板名 短名称 语言 标记
---------------------------------- -------------- ---- --------------------------------------------------------
BitzOrcas.Modern Solution Template bitzorcas-host [C#] Architecture/Clean Architecture/Modular Monolith/Web/API

4. Verify resolved composition

Terminal window
# The first group proves that caller selections resolved correctly.
# The latter fields prove optional extension and physical project closure.
jq '{
profileChoice,
profileId,
runtimeAdapter,
tenancy,
deployment,
platformModule,
industryExtension,
hosts,
projects
}' composition-manifest.json

Expected values are:

FieldExpected
profileChoicedefault-business-multi
profileIddefault-business
runtimeAdaptersqlsugar
tenancymulti
deploymentaspire
platformModule / industryExtensionnone / none
hostsapi, service-defaults, apphost

Check the plan and physical output:

Terminal window
# Plan proves which projects and entries were selected.
jq '{selectedProjects, selectedEndpoints, selectedJobs}' \
composition-plan.json
# Physical assertions prove Starter/AppHost exist and maintenance tools did not leak.
test -f src/Modules/Business/Starter/Acme.ServiceDesk.Modules.Business.Starter.Contracts/WorkItem.cs
test -f src/Hosts/Acme.ServiceDesk.AppHost/Program.cs
test ! -d tools

5. Restore commercial packages

Terminal window
dotnet restore Acme.ServiceDesk.slnx
find . -name packages.lock.json -print

First restore creates lock files. Review package IDs, versions, and sources before committing. Stable failure boundaries:

  • BITZFEED001: Feed URL not injected;
  • 401/403 or authentication-related NU1301: credential missing, expired, or revoked;
  • NU1101/NU1102: entitlement or channel does not cover the package;
  • NU3000: signature or certificate policy failed;
  • locked mode: requested closure differs from reviewed locks.

Never append tokens to a Feed URL, command argument, or diagnostic log.

6. Build and test

Terminal window
# Release Build consumes the already-restored locked closure.
dotnet build Acme.ServiceDesk.slnx \
--configuration Release \
--no-restore
# Full-solution tests include both Unit and Architecture gates.
dotnet test Acme.ServiceDesk.slnx \
--configuration Release \
--no-build \
--no-restore

Generated tests cover at least:

  • Profile, license-feature, and selected-ORM closure;
  • Starter Aggregate title and tenant invariants;
  • schema adoption;
  • no copied Framework/Platform source;
  • Application has no ORM or Host reference;
  • Handler, Endpoint, Aggregate, and owner boundaries remain local.

Passing establishes a generated baseline. It does not prove later business rules, permissions, or production configuration.

7. Configure AppHost parameters

AppHost injects two values into the long-running API:

Terminal window
# WorkerId is unique per instance within one data center.
dotnet user-secrets \
--project src/Hosts/Acme.ServiceDesk.AppHost \
set "Parameters:persistence-worker-id" "1"
# DataCenterId is deployment-assigned and must not be randomized per instance.
dotnet user-secrets \
--project src/Hosts/Acme.ServiceDesk.AppHost \
set "Parameters:persistence-data-center-id" "0"

WorkerId is 1..31 and unique per concurrent instance in a data center. DataCenterId is 0..31 and allocated per deployment. Missing or invalid values fail startup with Host.Persistence.Identity.Invalid.

Development includes a local JWT example. Production supplies Authentication:Jwt:Issuer, Audience, and a SigningKey of at least 32 UTF-8 bytes through a secret store.

8. Run Aspire

Terminal window
dotnet run --project \
src/Hosts/Acme.ServiceDesk.AppHost/Acme.ServiceDesk.AppHost.csproj

In the Aspire Dashboard, verify:

  1. sql and PrimaryDatabase become ready;
  2. schema-migrator exits successfully after --migrate-schema apply;
  3. api starts afterward;
  4. API receives ConnectionStrings:PrimaryDatabase and both Persistence values.

AppHost is development orchestration; it does not change the API configuration contract. Production supplies the same keys and runs a controlled schema runbook.

9. Verify health and OpenAPI

Obtain the API URL from the Dashboard:

Terminal window
curl --fail http://localhost:<api-port>/health/live
curl --fail http://localhost:<api-port>/health/ready
curl --fail http://localhost:<api-port>/openapi/v1.json
PathCurrent meaning
/health/liveprocess liveness
/health/readybase runtime dependencies; License absence alone does not fail it
/health/licenseRuntime License readiness
/scalar/v1interactive documentation enabled by default in Development

The template registers JWT Bearer only and has no login page. Scalar requires a token from the customer’s authentication entry.

10. Inspect Business Starter

Starter is not an empty placeholder. It includes a tenant WorkItem aggregate, CreateWorkItemCommand, handler, generated endpoint, unified repository, and stable errors:

Terminal window
rg -n 'WorkItem|CreateWorkItem|BusinessStarterErrors|GenerateEndpoint' \
src/Modules/Business/Starter

WorkItem is both the domain and persistence fact model. Metadata drives ORM generation; there is no separate Entity, Mapper, DataPort, or Infrastructure project. Replace example semantics while retaining the vertical-slice shape.

11. Schema operations

Multi AppHost already applies schema during development startup. Production still records the command and exit evidence separately:

Terminal window
dotnet run --project \
src/Hosts/Acme.ServiceDesk.Api/Acme.ServiceDesk.Api.csproj \
-- --migrate-schema apply

Schema mode loads only ConnectionStrings:PrimaryDatabase; it does not require JWT, tenant, License, or ServiceDefaults. Invalid action returns 2, missing database returns 3, and execution failure returns 1.

12. License and production boundary

Development defaults Licensing:Runtime:Enabled=false. Enabling production licensing requires Product, Version, Environment, TenancyMode, Deployment identity, Cache path, and at least one TrustedPublicKey. Missing values fail as Host.Licensing.Configuration.Invalid.

After template completion, add:

  • real aggregates, permission catalogs, and tenant/data-scope tests;
  • production JWT issuance and key rotation;
  • Runtime License acquisition, cache, revocation, and offline policy;
  • schema backup, rollback, exclusion, and production approval;
  • proxy, OpenAPI access, monitoring, and alerting;
  • frontend, deployment artifacts, and data migration.

Completion criteria

  • manifest Profile/ORM exactly match the command;
  • output has no maintenance scripts or foundation source copies;
  • commercial package locks are reviewed;
  • Release Build, Unit Tests, and Architecture Tests pass;
  • AppHost orders Database → Migrator → API;
  • live, ready, and license health meanings stay separate;
  • Starter unified aggregate/repository/Endpoint paths are located;
  • secrets, Feed tokens, and License private keys remain outside the repository;
  • unfinished production work is captured in backlog and runbooks.

See also

100%

Scroll or use controls to zoom · drag when enlarged · double-click for 100% / 200%