Substantive.ComponentModel.SourceGenerators 9.17.4-build20260115r1

Substantive.ComponentModel.SourceGenerators

Incremental Roslyn generators that implement common metadata interfaces in the Substantive.ComponentModel stack. Each generator discovers partial classes or records annotated with a matching attribute and injects the interface implementation so you avoid repetitive boilerplate when modeling domain, data-transfer, or view models.

Included generators

Attribute Interface implemented Members emitted
SoftDeleteMetadataAttribute ISoftDeleteMetadata bool IsDeleted, DateTimeOffset? DeletedAt
TimestampMetadataAttribute ITimestampMetadata DateTimeOffset CreatedAt, DateTimeOffset UpdatedAt (initialized to the same timestamp)
SchemaVersionMetadataAttribute ISchemaVersionMetadata string SchemaVersion (defaults to "1")
MultiTenantMetadataAttribute IMultiTenantMetadata string TenantId

All generators share the same discovery rules:

  • Targets must be partial classes or records.
  • Apply the corresponding attribute from Substantive.ComponentModel.
  • Add [IgnoreSourceGen] (or derive from IgnoreSourceGenAttribute) to opt out on a specific type.

Getting started

  1. Reference the analyzer NuGet in the consuming project (the generator compiles for netstandard2.0, so it works on .NET Framework, .NET Core, .NET, and Xamarin/MAUI targets).
    <PackageReference Include="Substantive.ComponentModel.SourceGenerators" PrivateAssets="all" />
    <PackageReference Include="Substantive.ComponentModel" />
    
  2. Mark eligible models as partial and decorate them with the metadata attributes you need.
  3. Build the project; the generator runs at compile time and emits the interface members into *.g.cs artifacts under obj/.

Usage example

using Substantive.ComponentModel;

[SoftDeleteMetadata]
[TimestampMetadata]
[SchemaVersionMetadata]
public partial record CaseFile
{
    public Guid Id { get; init; }
    public string Title { get; init; }
}

After compilation the partial record implements ISoftDeleteMetadata, ITimestampMetadata, and ISchemaVersionMetadata, so you can inject CaseFile into services that expect those contracts without hand-writing the repetitive properties.

Build, pack, and test

  • dotnet build src/BuildingBlocks/ComponentModel.SourceGenerators/ComponentModel.SourceGenerators.csproj compiles analyzers and verifies Roslyn APIs.
  • dotnet pack ... -c Release produces a NuGet package that already includes readme.md and icon.png.
  • Add CI steps to copy the produced Substantive.ComponentModel.SourceGenerators.dll into analyzers/dotnet/cs/ inside the nupkg (the project file already configures this).

Troubleshooting

  • Ensure consumers use the same version of Substantive.ComponentModel so the attribute namespaces match the generator expectations.
  • Keep model files nullable-enabled; the generated members respect the project-wide nullable context.
  • If you modify the attributes or interfaces, update the generator constants (InterfaceTypeName / FullyQualifiedAttributeName) to keep them synchronized.

Showing the top 20 packages that depend on Substantive.ComponentModel.SourceGenerators.

Packages Downloads
Substantive.Foundation.Backends
A metapackage contains all Substantive backend building blocks.
1
Substantive.Foundation.Backends
A metapackage contains all Substantive backend building blocks.
2

Version Downloads Last updated
9.17.21-build20260204R1 0 02/04/2026
9.17.20-build20260203R1 2 02/03/2026
9.17.19-build20260130R1 3 01/30/2026
9.17.18-build20260129R1 1 01/29/2026
9.17.17-build20260129R1 5 01/29/2026
9.17.17-build20260128R1 3 01/28/2026
9.17.16-build20260127R2 4 01/27/2026
9.17.16-build20260123R1 3 01/23/2026
9.17.15-build20260122R1 5 01/22/2026
9.17.14-build20260122R2 6 01/22/2026
9.17.14-build20260122R1 2 01/22/2026
9.17.14-build20260121R1 2 01/21/2026
9.17.13-build20260121R1 2 01/21/2026
9.17.12-build20260120R1 6 01/20/2026
9.17.11-build20260120R1 5 01/20/2026
9.17.10-build20260120R1 4 01/20/2026
9.17.9-build20260119R1 3 01/19/2026
9.17.8-build20260119R1 2 01/19/2026
9.17.7-build20260115R1 1 01/15/2026
9.17.6-build20260115R1 2 01/15/2026
9.17.5-build20260115R1 1 01/15/2026
9.17.4-build20260115R1 4 01/15/2026
9.17.3-build20260115R1 1 01/15/2026
9.17.2-build20260115R1 1 01/15/2026
9.17.2-build20260113R1 5 01/13/2026
9.17.1-build20260113R2 1 01/13/2026
9.17.1-build20251231R2 1 12/31/2025
9.17.1-build20251230R2 10 12/30/2025
9.17.1-build20251230R1 1 12/30/2025
9.17.0-build20251226R1 9 12/26/2025
9.17.0-build20251225R1 3 12/25/2025
9.16.0-build20251224R1 8 12/24/2025
9.15.3-build20251224R1 2 12/24/2025
9.15.2-build20251224R1 1 12/24/2025
9.15.1-build20251224R1 1 12/24/2025
9.15.0-build20251224R1 1 12/24/2025
9.14.4-build20251224R1 1 12/24/2025
9.14.3-build20251224R4 1 12/24/2025
9.14.2-build20251224R1 1 12/24/2025
9.14.1-build20251224R1 1 12/24/2025
9.14.0-build20251223R1 4 12/23/2025
9.12.0-build20251223R1 2 12/23/2025
9.3.0-build20251223R4 1 12/23/2025
9.3.0-build20251223R3 4 12/23/2025
9.3.0-build20251223R2 1 12/23/2025
9.3.0-build20251223R1 2 12/23/2025
9.3.0-build20251222R2 3 12/22/2025
9.3.0-build20251222R1 3 12/22/2025
9.2.0-build20251222R2 3 12/22/2025
9.2.0-build20251222R1 3 12/22/2025
9.1.0-build20251218R1 2 12/18/2025
9.1.0-build20251217R2 3 12/17/2025
9.1.0-build20251217R1 6 12/17/2025
9.1.0-build20251216R2 5 12/16/2025
9.1.0-build20251216R1 3 12/16/2025
9.1.0-build20251215R1 5 12/15/2025
9.1.0-build20251212R1 4 12/12/2025
9.1.0-build20251211R1 1 12/11/2025
9.1.0-build20251210R1 4 12/10/2025
9.1.0-build20251202R2 4 12/02/2025
9.1.0-build20251202R1 1 12/02/2025
9.1.0-build20251201R1 1 12/01/2025
9.0.5-build20251126R4 2 11/26/2025
9.0.5-build20251126R3 2 11/26/2025
9.0.5-build20251126R2 2 11/26/2025
9.0.5-build20251126R1 1 11/26/2025
1.1.0-build20251224R1 1 12/24/2025