Stratara.Domain
3.1.3
dotnet add package Stratara.Domain --version 3.1.3
NuGet\Install-Package Stratara.Domain -Version 3.1.3
<PackageReference Include="Stratara.Domain" Version="3.1.3" />
<PackageVersion Include="Stratara.Domain" Version="3.1.3" />
<PackageReference Include="Stratara.Domain" />
paket add Stratara.Domain --version 3.1.3
#r "nuget: Stratara.Domain, 3.1.3"
#:package Stratara.Domain@3.1.3
#addin nuget:?package=Stratara.Domain&version=3.1.3
#tool nuget:?package=Stratara.Domain&version=3.1.3
Stratara.Domain
License: FSL-1.1-MIT (Functional Source License — source-available; converts to MIT after 2 years). Not OSI-approved OSS.
The Stratara framework's concrete multitenancy domain — the Tenant aggregate and its event vocabulary. Use this when your application wants Stratara's opinionated tenant model (one tenant per customer, lifecycle events for activate / deactivate / rename / locale-change / assignment) and the corresponding aggregate.
Contents
Stratara.Domain.Multitenancy.Tenant— the aggregate. ImplementsIAggregate(fromStratara.Abstractions).Stratara.Domain.TenantCreated/TenantRenamed/TenantActivated/TenantDeactivated/TenantDefaultLocaleChanged/TenantAssignedToCustomer/TenantDeleted/CustomerTenantsDeleted— the event records consumed by the aggregate'sApply()methods + persisted to the event stream.
When to skip this package
If you're building a Stratara-on-Mediator application without the framework's tenant model (e.g. you have your own tenancy concept), reference Stratara.Abstractions alone for the marker interfaces. Most Stratara features (CQRS, event sourcing, projections, sagas) don't depend on Stratara.Domain.
Quick reference
// Open a Tenant stream from a command handler
await events.CreateAsync<Tenant>(tenantId,
new TenantCreated(
Id: tenantId,
CustomerId: customerId,
Name: "Acme",
DefaultLocale: "de-DE",
IsActive: true,
CreatedAt: DateTimeOffset.UtcNow),
cancellationToken);
await events.SaveChangesAsync(cancellationToken);
// Later: rehydrate the aggregate
var tenant = await aggregator.AggregateAsync<Tenant>(tenantId, cancellationToken: cancellationToken);
Dependencies
Stratara.Abstractions— forIAggregate(Tenant implements it).JetBrains.Annotations— for static-analysis attributes.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- JetBrains.Annotations (>= 2025.2.4)
- Stratara.Abstractions (>= 3.1.3)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Stratara.Domain:
| Package | Downloads |
|---|---|
|
Stratara.Shared
Umbrella package for the Stratara framework — source-generated logger extensions for outbox / saga / projection / messaging, domain-event helpers, merge primitives, and the Tier-A/B abstractions surface re-exported as one transitive bundle. |
|
|
Stratara.Projections
Projection runtime for the Stratara event-sourced stack — projection-handler discovery, change-set creation, update application, and projection manager. Sits between read-model repositories and the event-bundle dispatcher. |
|
|
Stratara.Sagas
Saga runtime for the Stratara event-sourced stack — ISaga discovery, manager / handler dispatch, cached method invoker, and a hosted SagaWorker that routes incoming event bundles to matching sagas. |
GitHub repositories
This package is not used by any popular GitHub repositories.
### Added
- **Mediator tenant-isolation behavior** (`Stratara.Mediator`) — `AddStrataraTenantIsolation()`
registers a pipeline behavior that enforces tenant isolation at the mediator entrance, before the
handler runs, for any request that opts in via the new `ITenantScopedRequest` marker
(`Stratara.Abstractions.Multitenancy`). The behavior compares the request's `TenantId` (data owner)
against the ambient session's data-owner tenant and rejects a mismatch with the new
`TenantAccessDeniedException` (translated to HTTP 403 on ASP.NET hosts). `TenantIsolationMode.Default`
enforces only the subject match (privileged cross-tenant operations pass when the endpoint promoted
the session subject to the target); `TenantIsolationMode.Strict` additionally routes every
cross-tenant operation through the new `ICrossTenantAuthorizer`, whose shipped default denies all
cross-tenant access until a consumer registers its own authorizer. Complements the existing
database-side `ApplyGlobalTenantQueryFilters` with a command-/query-entrance guard. New log-event
IDs `114_101`/`114_102`/`114_003` in `Stratara.Diagnostics`.
- **`Stratara.Abstractions.Persistence.ConcurrencyConflictException`** — provider-agnostic
wrapper for an optimistic-concurrency conflict detected during commit. Allows framework-level
code in `Stratara.Projections` (and any consumer outside the `EntityFrameworkCore` package) to
react to concurrency without taking an EF Core dependency. EF Core's `DbUpdateConcurrencyException`
(and provider equivalents) flow through this type.
### Changed
- **`EfTransaction.SaveChangesAsync`** (in `Stratara.EventSourcing.EntityFrameworkCore`) now
wraps `DbUpdateConcurrencyException` thrown by EF Core in the new
`ConcurrencyConflictException`. PostgreSQL unique-violation paths remain on `DbUpdateException`
(different semantics — duplicate-key on insert vs. stale-row on update/delete).
- **`EventSource.SaveChangesAsync`** (write-side append flow) extends its concurrency-handling
catch to the new exception type so the existing append-conflict recovery path keeps working
after the wrap. Behaviour for both EF concurrency conflicts and PostgreSQL unique violations
is unchanged.
### Fixed
- **`TenantProjection` no longer aborts the event bundle on a parallel delete race.** The two
delete handlers (`TenantDeleted`, `CustomerTenantsDeleted`) now swallow
`ConcurrencyConflictException` silently — a missing row is the desired end-state of a delete.
Before this fix, a consumer-side customer-delete cascade saga that emits both
`CustomerTenantsDeleted` and a follow-up `TenantDeleted` for the same tenants would race the
two parallel projection bundles on the same `TenantView` row; the loser threw
`DbUpdateConcurrencyException` out of `SaveChangesAsync`, which propagated through
`ProjectionWorker` and caused `RabbitMqBus` to roll back the entire bundle — including
sibling projections that had already committed. Update handlers (rename / activate /
deactivate / locale / customer-assigned) keep their current behaviour: a concurrency failure
there is a real race that propagates.