Muonroi.Tenancy.SiteProfile.SourceGenerators
2.0.2
dotnet add package Muonroi.Tenancy.SiteProfile.SourceGenerators --version 2.0.2
NuGet\Install-Package Muonroi.Tenancy.SiteProfile.SourceGenerators -Version 2.0.2
<PackageReference Include="Muonroi.Tenancy.SiteProfile.SourceGenerators" Version="2.0.2" />
<PackageVersion Include="Muonroi.Tenancy.SiteProfile.SourceGenerators" Version="2.0.2" />
<PackageReference Include="Muonroi.Tenancy.SiteProfile.SourceGenerators" />
paket add Muonroi.Tenancy.SiteProfile.SourceGenerators --version 2.0.2
#r "nuget: Muonroi.Tenancy.SiteProfile.SourceGenerators, 2.0.2"
#:package Muonroi.Tenancy.SiteProfile.SourceGenerators@2.0.2
#addin nuget:?package=Muonroi.Tenancy.SiteProfile.SourceGenerators&version=2.0.2
#tool nuget:?package=Muonroi.Tenancy.SiteProfile.SourceGenerators&version=2.0.2
Muonroi.Tenancy.SiteProfile.SourceGenerators
Roslyn source generators and analyzers that make multi-site
ISiteProfileregistration AOT-safe and type-checked at compile time.
This package is an analyzer/source-generator-only assembly (targets netstandard2.0, placed under analyzers/dotnet/cs). It ships four incremental source generators and eight diagnostic analyzers for the Muonroi.Tenancy.SiteProfile ecosystem. There is no runtime API — all behavior is compile-time code generation and static analysis.
Installation
dotnet add package Muonroi.Tenancy.SiteProfile.SourceGenerators --prerelease
The package is resolved as a Roslyn analyzer/generator reference. No <PackageReference> with OutputItemType="Analyzer" is required — the NuGet metadata handles placement automatically.
Quick Start
1. Declare a site profile with [GenerateSiteProfile]
using Muonroi.Tenancy.SiteProfile;
[GenerateSiteProfile("TCI", typeof(TciDbContext))]
[SiteProfileBehavior(typeof(TciCacheBehavior))]
public partial class TciSiteProfile : ISiteProfile
{
public string SiteId => "TCI";
// Generated partial void RegisterAdditionalServices(...) is your extension hook.
// The generator emits RegisterServices(...) — do not write it manually.
partial void RegisterAdditionalServices(
IServiceCollection services, IConfiguration configuration)
{
services.AddKeyedScoped<IOrderService, TciOrderService>("TCI");
}
}
The generator emits TciSiteProfile.RegisterServices.g.cs containing a RegisterServices(IServiceCollection, IConfiguration) implementation that calls SiteProfileBootstrap.RegisterSiteServices(...) and then invokes your RegisterAdditionalServices hook.
2. Register all discovered profiles (AOT-safe, no reflection)
// Program.cs — replaces reflection-based AddMultiSiteProfiles(Assembly[])
builder.Services.AddGeneratedSiteProfiles(
builder.Configuration,
siteCodeAccessor: sp => sp.GetRequiredService<ISiteProfileResolver>().CurrentSiteId);
AddGeneratedSiteProfiles is emitted by SiteProfileRegistrationGenerator into SiteProfileRegistrationExtensions.g.cs. It instantiates each discovered ISiteProfile via new TProfile() — no Activator.CreateInstance.
3. Use the generated SiteIds constants
// Instead of: services.AddKeyedScoped<IOrderService, TciOrderService>("TCI");
// Use:
services.AddKeyedScoped<IOrderService, TciOrderService>(SiteIds.TCI);
Analyzer MSP001 warns whenever a raw string literal matches a known SiteId value but SiteIds.<NAME> is not used.
Features
SiteProfileRegistrationGenerator— scans allISiteProfileimplementations and emits:SiteProfileRegistrationExtensions.g.cswithAddGeneratedSiteProfiles(IServiceCollection, IConfiguration, Func<IServiceProvider, string?>)— AOT-safe alternative to reflection-based registrationSiteIds.g.cswithinternal static class SiteIdscontaining oneconst stringper discovered profileSiteDbContextTypeRegistry.g.cswithGetAllSiteDbContextTypes()— AOT-safe migration runner supportSiteGrpcServiceRegistry.g.cswithGetAllSiteGrpcServices()— discovers[SiteGrpcService]from both local source and referenced assembliesSiteEntityTypeRegistry.g.cswithGetAllSiteEntityTypes()— entity hierarchy mappings from[SiteEntityMap]
SiteProfileScaffoldingGenerator— for each class decorated with[GenerateSiteProfile("siteId", typeof(DbContext))], emits a per-class partialRegisterServices(...)implementation plus an optionalApplyEntityHierarchy(ModelBuilder)method when[SiteEntityMap]attributes are presentSiteProfileAliasGenerator— for classes decorated with[SiteProfileAlias("TARGET")], emits aRegisterAliasServices(IServiceCollection)partial method that forwards keyed service registrations from the target site; enforcesMSP030/MSP031SiteGrpcFacadeGenerator— for partial interfaces decorated with[GenerateSiteGrpcFacade(SharedClient = typeof(X))], emits a partial interface completion with async RPC signatures plus a concrete{Name}Facadeclass that delegates each call to the correct inner gRPC client
Diagnostics
| ID | Severity | Title |
|---|---|---|
MSP001 |
Warning | Use SiteIds constant instead of a string literal for a known SiteId value |
MSP002 |
Warning | Site ISiteProfile class is missing a keyed DI registration for a type registered via AddSiteResolvedService<T>() |
MSP010 |
Info | [GenerateSiteProfile]-decorated class is not partial — add partial to enable scaffolding |
MSP020 |
Warning | Duplicate proto message name clashes with a shared assembly message |
MSP021 |
Warning | gRPC service class derives from a gRPC base but is missing [SiteGrpcService("SITE_ID")] |
MSP022 |
Warning | [SiteGrpcService]-decorated type is absent from the generated SiteGrpcServiceRegistry — rebuild required |
MSP023 |
Info | Site gRPC service class could inherit from a shared service to reuse RPC implementations |
MSP030 |
Warning | [SiteProfileAlias] used together with [SiteProfileBehavior] — behaviors may not apply as expected |
MSP031 |
Error | [SiteProfileAlias] requires [GenerateSiteProfile] on the same class |
MSP040 |
Warning | ISiteColumnMap is missing a Column() mapping for an entity property |
MSP041 |
Info | ISiteProfile in a referenced assembly may not be discovered — add its assembly to SiteAssemblies |
API Reference
This package has no runtime API. All public surface is Roslyn generator/analyzer infrastructure.
| Type | Purpose |
|---|---|
SiteProfileRegistrationGenerator |
IIncrementalGenerator — scans ISiteProfile impls; emits AddGeneratedSiteProfiles, SiteIds, SiteDbContextTypeRegistry, SiteGrpcServiceRegistry, SiteEntityTypeRegistry |
SiteProfileScaffoldingGenerator |
IIncrementalGenerator — emits per-class RegisterServices partial and ApplyEntityHierarchy from [GenerateSiteProfile] + [SiteEntityMap] |
SiteProfileAliasGenerator |
IIncrementalGenerator — emits RegisterAliasServices partial from [SiteProfileAlias]; enforces MSP030/MSP031 |
SiteGrpcFacadeGenerator |
IIncrementalGenerator — emits gRPC facade interface completion and concrete facade class from [GenerateSiteGrpcFacade] |
SiteIdLiteralAnalyzer |
DiagnosticAnalyzer — MSP001 |
ContractComplianceAnalyzer |
DiagnosticAnalyzer — MSP002 |
SiteProfileScaffoldingGenerator (diagnostic path) |
MSP010 |
DuplicateProtoMessageAnalyzer |
DiagnosticAnalyzer — MSP020 |
MissingSiteGrpcServiceAttributeAnalyzer |
DiagnosticAnalyzer — MSP021 |
SiteGrpcServiceRegistryAnalyzer |
DiagnosticAnalyzer — MSP022 |
InheritanceHintAnalyzer |
DiagnosticAnalyzer — MSP023 |
SiteProfileAliasGenerator (diagnostic path) |
MSP030, MSP031 |
ColumnMapDriftAnalyzer |
DiagnosticAnalyzer — MSP040 |
AssemblyIsolationHintAnalyzer |
DiagnosticAnalyzer — MSP041 |
Samples
No dedicated sample project is provided for this package. The generated extension methods (AddGeneratedSiteProfiles, SiteIds, RegisterAdditionalServices) are exercised in the host project of any service that references Muonroi.Tenancy.SiteProfile.
Compatibility
- Target framework:
netstandard2.0 - Roslyn component (
<IsRoslynComponent>true</IsRoslynComponent>) - License: Apache-2.0 (OSS)
Related Packages
Muonroi.Tenancy.SiteProfile— definesISiteProfile,ISiteProfileResolver,AddSiteResolvedService<T>(), andAddMultiSiteProfiles()— required runtime counterpartMuonroi.Tenancy.SiteProfile.Generated.Runtime— providesSiteProfileBootstrap.RegisterSiteServices(...)andSiteProfileManifestRunner.Register(...)called by the generated codeMuonroi.Tenancy.SiteProfile.Web— addsAddSiteProfileWeb(), per-request middleware, EF Core / Dapper per-site DI helpers
Ecosystem Combinations
+ SiteProfile → Generated Registration Code
Source generators scan for ISiteProfile implementations and emit partial classes with RegisterSiteServices() calls — replacing the entire manual AddSiteProfile<T>() boilerplate.
+ SiteProfile.Web → Generated Middleware Wiring
Generated code includes the middleware registration order for SiteProfileStateMiddleware — no manual app.UseSiteProfile() calls needed.
+ Data.EntityFrameworkCore → Generated DbContext Registration
For each ISiteProfile, the generator emits code to register AddSiteDbContext<T>() with the correct connection string from the site profile.
Samples
License
Apache-2.0. See LICENSE-APACHE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
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 |
|---|---|---|
| 2.0.2 | 148 | 8/26/2026 |
| 2.0.1 | 110 | 8/26/2026 |
| 2.0.0 | 125 | 8/14/2026 |
| 1.0.0-alpha.18 | 72 | 8/14/2026 |
| 1.0.0-alpha.16 | 95 | 6/22/2026 |
| 1.0.0-alpha.15 | 74 | 5/31/2026 |
| 1.0.0-alpha.14 | 76 | 5/15/2026 |
| 1.0.0-alpha.13 | 80 | 5/2/2026 |
| 1.0.0-alpha.12 | 99 | 4/2/2026 |
| 1.0.0-alpha.11 | 78 | 4/2/2026 |
| 1.0.0-alpha.10 | 72 | 3/31/2026 |
| 1.0.0-alpha.9 | 89 | 3/30/2026 |
| 1.0.0-alpha.8 | 382 | 3/28/2026 |
| 1.0.0-alpha.7 | 94 | 3/27/2026 |
| 1.0.0-alpha.5 | 81 | 3/27/2026 |
| 1.0.0-alpha.4 | 78 | 3/27/2026 |
| 1.0.0-alpha.3 | 81 | 3/27/2026 |
| 1.0.0-alpha.2 | 85 | 3/26/2026 |