SaaS domain implementation patterns¶
Wave-2 conventions shared by all five ConnectSoft.Saas.<Context>Template repositories. Entitlements is the reference for acceptance depth and gap traceability; Products Catalog is the reference for gRPC API documentation depth.
| Repo | Metrics class | Validators | Metrics unit tests |
|---|---|---|---|
| Tenants | TenantsMetrics |
8 | 5 |
| Products Catalog | ProductsCatalogMetrics |
9 | 6 |
| Entitlements | EntitlementsMetrics |
7 | 11 |
| Billing | BillingMetrics |
7 | 6 |
| Metering | MeteringMetrics |
8 | 6 |
Each template documents its concrete validator list and instrument names in docs/domain-implementation.md.
FluentValidation¶
- Validators live in
src/ConnectSoft.Saas.<Context>.DomainModel.Impl/Validators/. - One public validator class per file with Entitlements-style XML documentation.
Default*ProcessorandDefault*RetrieverinjectIValidator<TInput>and callValidateAndThrowAsyncbefore domain work.- Registration:
AddConnectSoftFluentValidation<MarkerValidator>assembly scan in<Context>MicroserviceRegistration. - Unit tests: one
*ValidatorUnitTests.csper validator undertests/.../DomainModel/Validators/.
dotnet test tests/ConnectSoft.Saas.<Context>.UnitTests/ConnectSoft.Saas.<Context>.UnitTests.csproj --filter "FullyQualifiedName~Validator"
Validation failures surface as REST problem details and, on gRPC, as ValidationFault (FaultContract strategy) or rich BadRequest details (RichError strategy).
Domain metrics¶
<Context>Metricsinsrc/ConnectSoft.Saas.<Context>.Metrics/.- OpenTelemetry meter name:
ConnectSoft.Saas.<Context>(see*MetricsMeterNameconstant). - Instrument naming:
{meter}.{operation}.{succeeded|failed}counters and{meter}.{operation}.durationhistograms (seconds). - Registration:
RegisterTemplateMetricsregisters the metrics singleton in<Context>MicroserviceRegistration. Default*ProcessorandDefault*Retrieverrecord success in the try path and failure in catch blocks (never alias unrelated instruments).
Unit tests use MetricCollector and Microsoft.Extensions.Diagnostics.Testing (see ConnectSoft.IdentityTemplate metrics tests for additional examples):
dotnet test tests/ConnectSoft.Saas.<Context>.UnitTests/ConnectSoft.Saas.<Context>.UnitTests.csproj --filter "FullyQualifiedName~Metrics"
Run across all five repos: 34 metrics tests (wave 2).
Note
SaaS templates use RegisterTemplateMetrics and dedicated *Metrics classes. The generic IMetricsFeature extension pattern in Metrics, Options and Testing Extensibility still applies to other templates (Identity, BaseTemplate features).
Processor and retriever logging¶
Follow DefaultEntitlementsProcessor:
using (logger.BeginScopeWithFlow(...))with tenant/aggregate correlation properties.logger.Here().LogInformation(...)at operation start.try/catch: error log + metrics failure recorder in catch; success log + metrics success recorder after commit.- Avoid logging before validation — validate first, then enter the scoped operation log.
gRPC rich errors¶
Each SaaS repo owns GrpcRichErrorInterceptor in src/ConnectSoft.Saas.<Context>.ApplicationModel/ (not the generic base-template copy). GrpcExtensions registers it when:
Supported values: FaultContract (ServiceModel.Grpc fault DTOs) and RichError (Google Rpc.Status with ErrorInfo, validation field violations, NHibernate mapping). See gRPC communication architecture for the platform-wide comparison.
XML documentation¶
ConnectSoft.Saas.<Context>.DomainModel, ServiceModel, and validator classes carry multi-line XML summaries. Interfaces document param and returns. Regenerated scaffolding from <Context>.json must be upgraded to this standard when touched.
Related documents¶
- SaaS Template Baseline Checklist — §15 domain implementation gate
- SaaS cross-repo published language — sample seed IDs
- Metrics, Options and Testing Extensibility
- Per-repo
docs/domain-implementation.md— context-specific validator and instrument inventory