Profiles & Metapackage Tailoring Architecture
In enterprise commercial software distribution, engineering teams face matrixed deployment requirements:
- Startup Teams: Need lightweight core API footprints (
Mini.Api) without heavy workflow state machines or large-scale reporting projections; - Enterprise On-Premises: Require complete workflow orchestration, audit table partitioning, S3-compatible file storage, and full operational capabilities (
Default.Business); - Group Portal Gateways: Require unified routing and aggregation endpoints (
Portal).
Maintaining distinct Git branches or declaring dozens of discrete package references for each scenario quickly causes dependency drift. BitzOrcas.Modern addresses this under src/Profiles/ via Metapackage Profiles.
1. Physical Structure and Role of Profiles
In the repository architecture, src/Profiles/ occupies the top-level orchestration tier:
2. Metapackage MSBuild Contract
A metapackage project contains zero C# source files. Its sole purpose is declaring versioning, licensing, and package dependency closures. Consider BitzOrcas.Profile.Default.Business.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <TargetFramework>net10.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable>
<!-- Metapackage flag: published as dependency aggregator with no local binary DLL --> <IsPackable>true</IsPackable> <PackageId>BitzOrcas.Profile.Default.Business</PackageId> <Title>BitzOrcas Profile — Default Business</Title> <Description>BitzOrcas tenant-neutral business system profile aggregating ORM-neutral Framework, Workflow, and fail-closed Licensing Runtime; specific ORM adapters are selected directly by the consumer.</Description> <PackageLicenseFile>LICENSE.txt</PackageLicenseFile> <Version>1.0.0-alpha1</Version> <PackageVersion>1.0.0-alpha1</PackageVersion> <PackAsTool>false</PackAsTool> <IncludeBuildOutput>false</IncludeBuildOutput> <NoWarn>$(NoWarn);NU5128</NoWarn> </PropertyGroup>
<!-- Auto-generated dependency version manifest --> <Import Project="..\Generated\BitzOrcas.Profile.Default.Business.g.props" />
<ItemGroup> <None Include="..\..\..\LICENSE.txt" Pack="true" PackagePath="\" /> </ItemGroup>
</Project>Key Property Analysis
<IncludeBuildOutput>false</IncludeBuildOutput>: Prevents emitting empty binary assemblies, packaging only nuspec metadata and dependency graphs;<Import Project="..\Generated\*.g.props" />: Enforces build-time consistency by importing catalog-verified dependency closures;<NoWarn>$(NoWarn);NU5128</NoWarn>: Suppresses NuGet warnings regarding empty build outputs.
3. Consumer Consumption Experience
For downstream business projects (such as src/Modules/Litigation), developers avoid declaring dozens of distinct platform packages. A single reference brings in the full verified commercial baseline:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <TargetFramework>net10.0</TargetFramework> <Nullable>enable</Nullable> </PropertyGroup>
<ItemGroup> <!-- Single line brings in Identity, Workflow, Audit, and core application capabilities --> <PackageReference Include="BitzOrcas.Profile.Default.Business" Version="1.0.0-alpha1" />
<!-- Explicitly select the preferred persistence adapter (SqlSugar or EF Core) --> <PackageReference Include="BitzOrcas.Infrastructure.SqlSugar" Version="1.0.0-alpha1" /> </ItemGroup>
</Project>4. Related Architecture Decisions & Deep Dives
- Golden Sample: Sandbox Golden Sample Architecture
- Modularity Core: BitzOrcas.Modularity Lifecycle & Auto-Wiring
- ADR Reference: ADR 0205: Commercial Package Distribution & Extension Model