Solution & Build Structure¶
This page explains how the Cargonerds repository is organised at the build level: the multiple
solution files, the central package- and version-management files, the NuGet feed setup, the ABP
Studio metadata, and the top-level folder layout. The goal is that you can open any .csproj,
.props, .sln or .abpsln file in the repo and know what it does and why.
For the conceptual layering of the projects (Domain / Application / EntityFrameworkCore / HttpApi / hosts) see Layered Architecture; for the framework patterns underneath them see ABP Framework Patterns. This page is about the build envelope around those projects.
The big picture¶
Cargonerds is a layered, tiered ABP commercial application generated from the ABP app
template (UI = Blazor WebAssembly, DB = SQL Server, distributed event bus = RabbitMQ,
multi-tenancy on). All first-party projects target .NET 10 (net10.0) and use ABP 10.1.1,
LeptonX 5.1.1, and Aspire 13.2.2 orchestration.
It is a monorepo holding the host application plus two custom ABP modules, and a separate frontend workspace:
| Part | Location | Notes |
|---|---|---|
Cargonerds (main app) |
src/, test/ |
The ABP app template host. |
Hub module |
modules/hub/ |
Shipments, Organizations, Tracking. Own ConnectionString Hub. |
Pricing module |
modules/pricing/ |
Pricing domain + its own Blazor WASM bundling project. |
frontend/ |
frontend/ |
npm workspace (Next.js realtime app + ui-library). Not part of the .NET build. |
Three mechanisms keep the build cohesive across all of that:
- One central package-version file —
Directory.Packages.propsgoverns the version of every NuGet package acrosssrc/,test/, and both modules. - One root
common.props—<Import>-ed by every first-party.csproj; it carries<Version>,LangVersion, the ABP/Aspire/LeptonX version variables, and shared MSBuild targets. - Multiple solution files — each solution file describes a different slice of the same project set (root app-only,
.All= everything, per-module).
flowchart TD
CP["common.props<br/>(Version, AbpVersion, LeptonXVersion,<br/>AspireVersion, test conventions)"]
DPP["Directory.Packages.props<br/>(~292 PackageVersion entries)"]
NC["NuGet.Config<br/>(nuget.org + ABP commercial feed)"]
CSPROJ["every first-party .csproj<br/>(Import common.props,<br/>versionless PackageReferences)"]
CP -->|"<Import>"| CSPROJ
DPP -->|"resolves PackageReference versions"| CSPROJ
CP -.->|"AbpVersion/etc. variables"| DPP
NC -->|"feed + source mapping"| CSPROJ
CSPROJ --> SLN["Cargonerds.sln (app only)"]
CSPROJ --> ALL["Cargonerds.All.sln / .slnx (everything)"]
CSPROJ --> HUB["modules/hub/Hub.sln"]
CSPROJ --> PRI["modules/pricing/Pricing.sln"]
No Directory.Build.props at the root
There is no root Directory.Build.props. The explicit <Import Project="..\..\common.props" />
line near the top of each .csproj is the deliberate equivalent — it makes the dependency on
shared props visible per project rather than implicit. (The only Directory.Build.props files in
the tree live inside the git-ignored abpSrc/ dumps and
affect only those copies.)
Solution files: .sln vs .All vs .slnx¶
The same set of projects is described by several solution files for different working scopes. Pick the one that matches what you want loaded into the IDE or built on the command line.
| File | Format | Scope | Project entries |
|---|---|---|---|
Cargonerds.sln |
Classic .sln (Format 12.00, VS 17) |
App only — src/ + test/ of the main app + the two Aspire projects |
28 Project( lines (incl. solution folders) |
Cargonerds.All.sln |
Classic .sln (Format 12.00, VS 18) |
Everything — app + Hub + Pricing | 66 Project( lines |
Cargonerds.All.slnx |
Modern XML .slnx |
Everything (the readable, authoritative listing) | grouped under solution folders |
modules/hub/Hub.sln |
Classic .sln |
Hub module only | 16 Project( lines |
modules/pricing/Pricing.sln |
Classic .sln |
Pricing module only | 17 Project( lines |
Key points:
Cargonerds.slnis the day-to-day app solution. It contains the main app'ssrc/andtest/projects plusCargonerds.AppHostandCargonerds.ServiceDefaults. It does not list the Hub/Pricing module projects as solution entries (those are pulled in transitively viaProjectReference, but they are not editable nodes in this solution tree).Cargonerds.All.slnis the superset that additionally lists everymodules/hub/**andmodules/pricing/**project. This is the solution CI and the test command use — the README runsdotnet test "Cargonerds.All.sln".Cargonerds.All.slnxis the new XML form of the All solution. It is the most readable listing and groups projects under solution folders such as/Cargonerds/src/,/Cargonerds/test/,/Cargonerds/aspire/,/Hub/src/,/Hub/test/,/Pricing/src/,/Pricing/test/, plus/Solution Items/(props, README, NuGet.Config,.editorconfig, the.abpmdl/.abpsln, the.github/workflows/, and the.scripts/) and/SqlQueries/.- The per-module solutions surface projects the All solution does not list as separate folders —
e.g.
Hub.slnincludesHub.SourceGenerators,Hub.Installer, andHub.UI;Pricing.slnincludesPricing.Blazor.WebAssembly,Pricing.Blazor.WebAssembly.Bundling, andPricing.Installer. Use a module solution when you want to work on just that module in isolation.
Which solution should I open?
- Working on the host app UI/API/domain →
Cargonerds.sln. - Touching Hub or Pricing alongside the app, or running the full test suite →
Cargonerds.All.slnx/Cargonerds.All.sln. - Hacking on one module in isolation → that module's
Hub.sln/Pricing.sln.
.slnx vs .sln drift, and no app-only .slnx
The All solution exists in both classic .sln and modern .slnx form, and the two must be
kept in sync by hand — adding a project to one does not update the other. The root app-only
Cargonerds.sln has no .slnx twin. When you add a project, update every solution file it
belongs to.
Solution membership is not the same as disk contents
Some folders on disk are not members of any solution and therefore will not build or test via
the All solution: test/Cargonerds.Integration.Tests and test/Cargonerds.ServiceDefaults.Tests
exist as folders but are absent from Cargonerds.All.slnx/.sln. Don't assume "it's in the repo"
means "it builds with the solution."
Directory.Packages.props: central package management¶
Cargonerds uses NuGet Central Package Management (CPM). Package versions are declared once in
the root Directory.Packages.props; individual .csproj files reference packages without a
version.
The root of the file turns CPM on and disables transitive pinning:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Aspire.Hosting.AppHost" Version="$(AspireVersion)" />
<!-- ~292 PackageVersion entries total -->
<PackageVersion Include="Riok.Mapperly" Version="4.3.1" />
</ItemGroup>
</Project>
There are roughly 292 <PackageVersion> entries. Note how the ABP / Aspire / LeptonX entries do
not hard-code a number — they reference MSBuild variables:
Volo.*packages useVersion="$(AbpVersion)"- LeptonX packages use
$(LeptonXVersion) - Aspire packages use
$(AspireVersion) - ABP Studio client uses
$(AbpStudioVersion)
Those variables are defined in common.props, not here (see the next section). That is the single
most important thing to understand about this file.
A consuming project then references the package with no version at all:
<!-- src/Cargonerds.Domain/Cargonerds.Domain.csproj -->
<PackageReference Include="Riok.Mapperly" />
<PackageReference Include="Volo.Abp.Emailing" />
<PackageReference Include="Volo.Abp.Caching" />
The version (4.3.1 for Mapperly, $(AbpVersion) → 10.1.1 for the Volo packages) is resolved from
Directory.Packages.props. Bumping ABP across the entire repo is therefore a one-line edit to
AbpVersion in common.props.
Where CPM version variables actually live
Editing $(AbpVersion) / $(LeptonXVersion) / $(AspireVersion) / $(AbpStudioVersion) means
editing common.props, not Directory.Packages.props. Because every .csproj imports
common.props before CPM is evaluated, those variables resolve correctly inside the
<PackageVersion> entries.
Transitive pinning is off
With CentralPackageTransitivePinningEnabled=false, transitive dependencies are not
auto-pinned to CPM — only your direct <PackageReference>s require a matching <PackageVersion>.
A known transitive mismatch (HtmlSanitizer pinning an older AngleSharp than other Volo packages
pull in) is pre-suppressed via NU1608 in common.props.
common.props: shared MSBuild properties¶
common.props (at the repo root) is <Import>-ed by every first-party project. It is small but
carries a lot of policy. Here is the full file:
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>3.1.4.0</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<SourceRevisionId>build$([System.DateTime]::UtcNow.ToString("yyyyMMddHHmmss"))</SourceRevisionId>
<!--
CS1591 : XML comment on public members (too noisy on generated DTOs).
NU1608 : HtmlSanitizer pins an older AngleSharp than other ABP/Volo deps pull in;
the higher version is compatible and ships in the final WASM bundle regardless.
-->
<NoWarn>$(NoWarn);CS1591;NU1608</NoWarn>
<AbpProjectType>app</AbpProjectType>
<AbpVersion>10.1.1</AbpVersion>
<AspireVersion>13.2.2</AspireVersion>
<LeptonXVersion>5.1.1</LeptonXVersion>
<AbpStudioVersion>2.2.1</AbpStudioVersion>
</PropertyGroup>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<PropertyGroup Condition="'$(IsTestProject)' == 'true' and '$(RunSettingsFilePath)' == ''">
<RunSettingsFilePath>$(MSBuildThisFileDirectory)test.runsettings</RunSettingsFilePath>
</PropertyGroup>
<ItemGroup Condition="'$(IsTestProject)' == 'true'">
<ProjectReference Include="$(MSBuildThisFileDirectory)\test\Cargonerds.Tests.Shared\Cargonerds.Tests.Shared.csproj" />
</ItemGroup>
<PropertyGroup Condition="'$(IsTestProject)' == 'true'">
<TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
</PropertyGroup>
<Target Name="NoWarnOnRazorViewImportedTypeConflicts" BeforeTargets="RazorCoreCompile">
<PropertyGroup>
<NoWarn>$(NoWarn);0436</NoWarn>
</PropertyGroup>
</Target>
<ItemGroup>
<None Remove="**\*.abppkg" />
<None Remove="**\*.abppkg.analyze.json" />
<Content Remove="$(UserProfile)\.nuget\packages\*\*\contentFiles\any\*\*.abppkg*" />
</ItemGroup>
</Project>
What it does, section by section:
- Versioning —
<Version>3.1.4.0</Version>is the single app version (this is what.scripts/UpdateVersion.ps1bumps, producing the recurringchore: bump version to ...commits).AssemblyVersionmirrors it, andSourceRevisionIdstamps a UTC build timestamp. - ABP / Aspire / LeptonX version variables —
AbpVersion,AspireVersion,LeptonXVersion,AbpStudioVersion. These are the source of truth thatDirectory.Packages.propsreferences. AbpProjectType=app— marks the host app for ABP tooling (the modules usemodule; see below).- CPM enabled here too (belt and braces) and warning suppressions —
CS1591(missing XML doc, noisy on generated DTOs) andNU1608. A second target appends0436right beforeRazorCoreCompileto silence Razor "imported type conflict" warnings. - Test-project conventions keyed on
'$(IsTestProject)' == 'true':- points
RunSettingsFilePathat the roottest.runsettings, - auto-adds a
ProjectReferencetotest/Cargonerds.Tests.Shared, - enables Microsoft.Testing.Platform (
TestingPlatformDotnetTestSupport=true).
- points
- ABP package hygiene — removes
*.abppkg/*.abppkg.analyze.jsonfrom the defaultNone/Contentglobs so they don't get treated as build content.
Per-module common.props¶
Each module has its own common.props (modules/hub/common.props,
modules/pricing/common.props). They mirror the root file but differ in a few ways:
<!-- modules/hub/common.props (excerpt) -->
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>1.0.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<AbpProjectType>module</AbpProjectType>
<AbpVersion>10.1.1</AbpVersion>
<LeptonXVersion>5.1.1</LeptonXVersion>
<AbpStudioVersion>2.2.1</AbpStudioVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ConfigureAwait.Fody" PrivateAssets="All" />
<PackageReference Include="Fody">
<PrivateAssets>All</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<!-- test projects point RunSettingsFilePath back to ..\..\test.runsettings -->
</Project>
Differences worth noting:
<AbpProjectType>module</AbpProjectType>instead ofapp.- Module-wide
Fody+ConfigureAwait.Fodypackage references (withPrivateAssets=All) — the modules weaveConfigureAwait(false)automatically; the host app does not. - Test projects'
RunSettingsFilePathand theCargonerds.Tests.Sharedreference point back to the root (..\..\test.runsettings,..\..\test\...), so module tests share the app's test config. <Version>1.0.0</Version>— see the gotcha below; module versions are independent of the app.
Module <Version> is independent of the app version
Hub and Pricing common.props both declare 1.0.0. Only the root common.props <Version>
(3.1.4.0) is the application version and the one UpdateVersion.ps1 bumps. Don't read a module
DLL's version as "the app version."
NuGet.Config: feeds and Package Source Mapping¶
The repo restores packages from two feeds and uses Package Source Mapping to decide which feed serves which package:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="nuget.abp.io" value="https://nuget.abp.io/1faf36a2-7070-4b97-aabc-1da41d63ed15/v3/index.json" />
</packageSources>
<packageSourceMapping>
<packageSource key="nuget.org">
<package pattern="*" />
<package pattern="Microsoft.*" />
<package pattern="Volo.*" />
</packageSource>
<packageSource key="nuget.abp.io">
<package pattern="Volo.*" />
</packageSource>
</packageSourceMapping>
</configuration>
nuget.orgserves everything (*), includingMicrosoft.*and — note — alsoVolo.*.nuget.abp.io/<license-guid>is the ABP commercial feed; the GUID in the URL is the organisation's license key. It serves the commercialVolo.*(e.g.Volo.Abp.Identity.Pro,Volo.CmsKit.Pro,Volo.Saas) packages that are not on nuget.org.
Because Volo.* is mapped to both feeds, NuGet will look on nuget.org for the open-source Volo
packages and fall through to the ABP feed for the commercial ones. You need access to the ABP
commercial feed (a valid license) to restore the solution.
Restoring without commercial access fails fast
If dotnet restore cannot reach nuget.abp.io, the *.Pro / commercial packages will not
resolve. This is expected — the build requires the ABP commercial license configured for the feed.
Local dotnet tools¶
.config/dotnet-tools.json pins the repo's local CLI tools, restored with dotnet tool restore:
{
"version": 1, "isRoot": true,
"tools": {
"csharpier": { "version": "1.2.6", "commands": ["csharpier"], "rollForward": false },
"husky": { "version": "0.7.2", "commands": ["husky"] }
}
}
- CSharpier 1.2.6 is the C# formatter, pinned with
rollForward: falseso formatting output is reproducible across machines (a newer CSharpier could reformat differently and break the CI format check). - Husky.Net 0.7.2 drives the git hooks. The pre-commit hook runs
dotnet husky run --group pre-commit(CSharpier over.cs, Prettier over stagedfrontend/files) and re-stages the formatted files. For the full hook story see the Development Workflow page.
ABP Studio & CLI metadata files¶
ABP Studio (and the abp CLI) keep their own description of the solution alongside MSBuild's. These
files drive ABP tooling — not dotnet build — so they can drift from the real build.
Cargonerds.abpmdl — main package manifest¶
The module manifest for the main package. It records "template": "app", the imports
(installed Volo modules and the versions ABP Studio thinks are installed), the folders (src,
test), and a packages map (every main-app project → its .abppkg file). It also imports the two
custom modules by path:
"Hub": { "path": "modules/hub/Hub.abpmdl", "isInstalled": true },
"Pricing": { "path": "modules/pricing/Pricing.abpmdl", "isInstalled": true }
Each custom module has its own .abpmdl (modules/hub/Hub.abpmdl,
modules/pricing/Pricing.abpmdl) mapping its Domain, Domain.Shared, Application(.Contracts),
EntityFrameworkCore, HttpApi(.Client), Installer, UI, and test packages.
Cargonerds.abpsln — ABP Studio solution descriptor¶
The ABP Studio solution file. It carries the solution id, a versions block, the three modules,
an Aspire runProfile and a Kubernetes k8sProfile, the Helm/Kubernetes commands ABP Studio
exposes (helmBuildDotnetImage, helmInstallChart, kubernetesRedeploy, …, all rooted at
etc/helm), the full Helm chart tree (authserver, blazor, dbmigrator, httpapihost,
webpublic, plus rabbitmq/redis/sqlserver), and the original createCommand:
abp new Cargonerds -t app --tiered --ui-framework blazor --mobile react-native
--database-provider ef --database-management-system sqlserver --theme leptonx
--public-website ...
It also records "useLocalReferences": "false" — confirming the app consumes ABP via NuGet, not via
the local source under abpSrc/.
.abpsln and .abpmdl versions are STALE — trust common.props for the real TFM/versions
The metadata files lag the real build. Cargonerds.abpsln versions says AbpFramework 10.0.0,
AbpCommercial 10.0.0, LeptonX 5.0.0, TargetDotnetFramework net9.0, and the imports in
Cargonerds.abpmdl list module versions like 9.3.1 / 4.3.1. The actual build is ABP
10.1.1 on net10.0 (from common.props and the <TargetFramework>net10.0</TargetFramework>
in every .csproj). When in doubt about a version or the target framework, read common.props
and the .csproj, not the .abpsln/.abpmdl (or the README, which still says ".NET 9").
abpSrc/: local ABP framework source¶
abpSrc/ holds local checkouts of ABP framework/module source — one directory per module
(Volo.Abp.Account, Volo.CmsKit, Volo.Saas, …). It is produced by abpSrc/abp-get-all-src.ps1,
which runs abp get-source list and then abp get-source <Module> into a folder per module.
It is git-ignored except the fetch script:
abpSrc/ is read-only debugging material — never reference it
No first-party project references abpSrc/. The app consumes ABP via NuGet
(useLocalReferences: false). abpSrc/ exists purely so you can read/step into framework
internals locally. Do not add ProjectReferences into it. Each abpSrc/*/Directory.Build.props
only affects those dumped trees and has no effect on the Cargonerds build.
SolutionPacker.exe¶
A standalone binary at the repo root (SolutionPacker.exe, dated January 2022, ~228 KB).
Orphaned — not part of the build
SolutionPacker.exe is not referenced by any .csproj, .props, git hook, or workflow. A
repository-wide search for SolutionPacker returns only the binary itself. Treat it as a leftover
utility, not part of packing, building, or CI.
Top-level folder layout¶
| Folder | Contents |
|---|---|
src/ |
Main-app projects (Domain.Shared → … → hosts) plus Cargonerds.AppHost, Cargonerds.ServiceDefaults, Cargonerds.UI.Shared. |
modules/hub/, modules/pricing/ |
The two custom ABP modules, each with its own src/ + test/ + .sln + common.props + .abpmdl. |
test/ |
Main-app tests. More projects on disk than in the solutions — Cargonerds.Integration.Tests and Cargonerds.ServiceDefaults.Tests are not in the solutions. |
frontend/ |
npm workspaces root ("workspaces": ["realtime","ui-library"]). realtime is a Next.js app; ui-library a shared TS component lib. Independent of MSBuild. |
etc/ |
Ops: abp-studio/ (run & k8s profiles), bruno/ (API client), docker/, docker-compose/, helm/ (per-service charts wired in Cargonerds.abpsln). |
.scripts/ |
Azure/DNS deploy PowerShell + UpdateVersion.ps1 (bumps <Version> in root common.props). |
.githooks/ |
core.hooksPath target — pre-commit formatting; install.ps1 writes the worktree excludes to .git/info/exclude. |
docs/ |
This MkDocs site (mkdocs.yml, requirements-docs.txt, gen_releases.py). |
abpSrc/ |
Git-ignored ABP source dumps (see above). |
Main-app project graph¶
The host follows the canonical ABP app layering, with the two custom modules wired in by
ProjectReference:
flowchart LR
DS["Domain.Shared"]
D["Domain"]
AC["Application.Contracts"]
A["Application"]
EF["EntityFrameworkCore<br/>(CargonerdsDbContext / Default)"]
HA["HttpApi"]
HAC["HttpApi.Client"]
HubD["Hub.Domain"]
PriD["Pricing.Domain"]
HubEF["Hub.EntityFrameworkCore"]
PriEF["Pricing.EntityFrameworkCore"]
AS["AuthServer"]
HAH["HttpApi.Host"]
WP["Web.Public"]
BL["Blazor"]
BLC["Blazor.Client (WASM)"]
DBM["DbMigrator"]
DS --> D
AC --> D
HubD --> D
PriD --> D
D --> A
D --> EF
HubEF --> EF
PriEF --> EF
A --> HA --> HAC
EF --> HAH
HA --> HAH
HA --> AS
HAC --> BL
BL --> BLC
EF --> DBM
Notable wiring (verified in the .csproj files):
Cargonerds.Domainreferences the modules' domain layers (Hub.Domain,Pricing.Domain,Pricing.Application.Contracts) in addition to the app's ownDomain.Shared/Application.Contracts.Cargonerds.EntityFrameworkCorereferencesHub.EntityFrameworkCore+Pricing.EntityFrameworkCoreand is whereCargonerdsDbContext(theDefaultconnection) lives. The Hub module owns its ownHubDbContext(Hubconnection) — see Hub Module.- ABP package references are deliberately split across multiple
ItemGroups by concern (framework infra in one group, the commercial "pro/feature modules" in another) — visible inCargonerds.Domain.csprojandCargonerds.EntityFrameworkCore.csproj.
For how custom modules are structured and consumed, see Module Structure.
Aspire orchestration projects¶
Two src/ projects belong to .NET Aspire rather than the ABP layering:
Cargonerds.AppHost— the Aspire host (<IsAspireHost>true</IsAspireHost>). ItProjectReferences the five runnable apps (AuthServer, Blazor, HttpApi.Host, Web.Public, DbMigrator) so Aspire can launch them, and it links shared source files instead of referencing whole projects (to avoid heavy graph pulls):
<Sdk Name="Aspire.AppHost.Sdk" Version="13.1.0" />
...
<Compile Include="..\..\modules\hub\src\Hub.Domain.Shared\WhiteLabeling\WhiteLabelingOptions.cs"
Link="LinkedFiles\WhiteLabelingOptions.cs" />
<Compile Include="..\Cargonerds.Domain.Shared\CargonerdsConsts.cs"
Link="LinkedFiles\CargonerdsConsts.cs" />
Cargonerds.ServiceDefaults— the standard Aspire shared OpenTelemetry / health-check / service-discovery project.
AspireVersion (13.2.2) is not the AppHost SDK version (13.1.0)
These are two different knobs. The Aspire packages are pinned via $(AspireVersion)=13.2.2 in
CPM, but Cargonerds.AppHost.csproj hard-codes <Sdk Name="Aspire.AppHost.Sdk" Version="13.1.0" />.
Updating one does not update the other.
See .NET Aspire Integration for the full AppHost story (linked-file pattern, ServiceDefaults, Nextended.Aspire).
How central versioning plays out in practice¶
- A project never specifies a version on a
<PackageReference>— the version always comes fromDirectory.Packages.props. - Bumping ABP across the whole repo is a one-line edit to
AbpVersionincommon.props(and the matching value in each module'scommon.props), because everyVolo.*entry in CPM isVersion="$(AbpVersion)". - Bumping the app version is a one-line edit to
<Version>in the rootcommon.props— automated by.scripts/UpdateVersion.ps1.
Gotchas (quick reference)¶
Build-truth checklist
.abpsln/.abpmdl/ README are stale for versions and TFM. Real values are incommon.props+.csproj(ABP 10.1.1, net10.0).- CPM version variables live in
common.props, notDirectory.Packages.props. CentralPackageTransitivePinningEnabled=false— only direct references need a<PackageVersion>;NU1608is pre-suppressed for the AngleSharp/HtmlSanitizer mismatch.AspireVersion(13.2.2) ≠ AppHost SDK (13.1.0).- Module
<Version>is1.0.0, independent of the app's3.1.4.0. .slnxand.sln(All) drift and must be hand-synced; app-only.slnhas no.slnxtwin.- Solution membership ≠ disk contents —
Cargonerds.Integration.TestsandCargonerds.ServiceDefaults.Testsare on disk but not in the solutions. SolutionPacker.exeis dead weight;abpSrc/is local-only and must never be referenced.
Related pages¶
- Architecture Overview — the system at a glance.
- Layered Architecture — what each project layer is for.
- ABP Framework Patterns — the framework concepts behind the layers.
- .NET Aspire Integration — AppHost, ServiceDefaults, orchestration.
- Module Structure · Hub Module · Pricing Module — the in-repo ABP modules.
- Development Workflow — git hooks, CSharpier/Husky, worktrees.
- Testing — the
Cargonerds.All.slntest entrypoint and conventions. - Running Locally — restoring,
abp install-libs, DbMigrator. - Helm & Kubernetes — the charts wired through
Cargonerds.abpsln. - CLI Commands —
abp/dotnetcommands used in this repo.