Documentation

reference/patterns/database-architecture.md

Database Architecture and Schema Isolation

Overview

The Dynaplex database architecture implements a sophisticated schema isolation system that prevents cross-schema pollution while enabling cross-component entity references. This document explains the complete architecture, from the foundational patterns to the automatic isolation mechanisms.

Table of Contents

  1. Architecture Principles
  2. Component Database Structure
  3. Schema Isolation Mechanism
  4. Prism Foundation
  5. Cross-Component References
  6. Migration Patterns
  7. Best Practices
  8. Common Pitfalls
  9. Troubleshooting

Architecture Principles

Single Database, Multiple Schemas

The Dynaplex architecture uses a single shared database instance with isolated schemas per component:

acsis (database)
├── prism (schema)       ← Foundation: passports, platform_types, journals
├── identity (schema)    ← Users, tenants, authentication
├── catalog (schema)     ← Items, item types, categories
├── spatial (schema)     ← Locations, buildings, regions
├── workflow (schema)    ← Process definitions, workflow runs
└── [other components]

Key Benefits:

  • Operational simplicity (single database to manage)
  • Cost efficiency (shared infrastructure)
  • Performance (connection pooling)
  • Clear service boundaries (schema isolation)

Reference: ADR-009: Database Schema per Service

Database Project Separation

Each component has a dedicated .Database project separate from .Abstractions:

engines/catalog/src/
├── Acsis.Dynaplex.Engines.Catalog.Abstractions/    # Interfaces, DTOs (no EF Core)
├── Acsis.Dynaplex.Engines.Catalog.Database/        # DbContext, entities, migrations
├── Acsis.Dynaplex.Engines.Catalog/                 # Service implementation
└── Acsis.Dynaplex.Engines.Catalog.DbMigrator/      # Migration runner

Why This Matters:

  • ✅ Abstractions remain pure contracts (no database dependencies)
  • ✅ Database entities hidden from API surface
  • ✅ Clear separation of concerns
  • ✅ Prevents circular dependencies

Reference: ADR-036: Database Project Separation

Component Database Structure

Standard Database Project Layout

Acsis.Dynaplex.Engines.Catalog.Database/
├── CatalogDb.cs                    # DbContext with schema configuration
├── CatalogDbContextFactory.cs      # Design-time factory for migrations
├── Item.cs                         # Entity classes
├── ItemType.cs
├── ItemCategory.cs
├── Configurations/                 # Optional: IEntityTypeConfiguration classes
│   ├── ItemConfiguration.cs
│   └── ItemTypeConfiguration.cs
└── Migrations/                     # EF Core migrations
    ├── 20251031120000_Initial.cs
    └── CatalogDbModelSnapshot.cs

DbContext Pattern

Every component's DbContext follows this pattern:

using Acsis.Dynaplex.Engines.Prism.Database;
using Acsis.Dynaplex;
using Microsoft.EntityFrameworkCore;

namespace Acsis.Dynaplex.Engines.Catalog.Database;

public partial class CatalogDb : DynaplexDbContext
{
    // 1. Define the schema constant (CRITICAL!)
    public const string SCHEMA = "catalog";

    // 2. Define DbSets for your entities
    public virtual DbSet<Item> Items { get; set; }
    public virtual DbSet<ItemType> ItemTypes { get; set; }

    // 3. Reference external entities you need
    public virtual DbSet<Passport> Passports { get; set; }
    public virtual DbSet<Tenant> Tenants { get; set; }

    // 4. Constructor
    public CatalogDb(DbContextOptions<CatalogDb> options) : base(options) { }

    // 5. OnModelCreating with standard pattern
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Apply configurations from this assembly
        modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());

        // Set default schema
        modelBuilder.HasDefaultSchema(SCHEMA);

        // Call base (applies tenant filtering)
        base.OnModelCreating(modelBuilder);

        // Configure external references
        modelBuilder.AddExternalReference<Passport>(Passport.TABLE_NAME, PrismDb.SCHEMA, p => p.GlobalId);
        modelBuilder.AddExternalReference<Tenant>(Tenant.TABLE_NAME, IdentityDb.SCHEMA, t => t.Id);

        // Auto-configure Passport relationships
        modelBuilder.ConfigurePassportRelationships(SCHEMA);

        // Add indexes for tenant-scoped entities
        modelBuilder.Entity<Item>().HasIndex(i => i.TenantId);

        // CRITICAL: Schema isolation (must be last!)
        modelBuilder.ConfigureSchemaIsolation(SCHEMA);

        OnModelCreatingPartial(modelBuilder);
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}

Key Components Explained

1. DynaplexDbContext Base Class

Located in: strata/core/src/Acsis.Dynaplex/DynaplexDbContext.cs

Provides:

  • Multi-tenancy support via _tenantId field
  • Automatic tenant filtering on all entities with TenantId property
  • DbContext pooling compatibility
  • Standard base configuration
public abstract class DynaplexDbContext : DbContext
{
    protected Guid? _tenantId;

    public void SetTenantId(Guid? tenantId) => _tenantId = tenantId;

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Applies tenant filters automatically
        modelBuilder.ConfigureTenantFilters(this);
    }
}

2. SCHEMA Constant

CRITICAL: Every DbContext must define a public const string SCHEMA field:

public const string SCHEMA = "catalog";

This constant:

  • Defines the schema name for all tables in this component
  • Is used by ComponentSchemaRegistry for assembly-to-schema mapping
  • Enables automatic schema isolation
  • Must match the schema naming convention (lowercase, singular)

Schema Naming Convention:

  • Use lowercase
  • Use singular form (e.g., "catalog" not "catalogs")
  • Match component name (e.g., "spatial", "identity", "workflow")

Schema Isolation Mechanism

The Problem

When a DbContext references entities from another component, EF Core attempts to create those tables in the current schema during migrations:

// In CatalogDb (schema = "catalog")
public DbSet<Passport> Passports { get; set; }  // From Prism (schema = "prism")

// Without schema isolation:
// Migration tries to: CREATE TABLE catalog.passports (...)
// Result: Duplicate table, FK constraint failures, schema pollution

The Solution: Automatic Schema Isolation

The Dynaplex architecture uses a three-part solution:

1. ComponentSchemaRegistry

Located in: strata/core/src/Acsis.Dynaplex/ComponentSchemaRegistry.cs

Purpose: Automatically discovers which schema each assembly "owns"

How it works:

  1. Scans all types in an assembly
  2. Finds any DbContext class
  3. Reads the public static SCHEMA field from that DbContext
  4. Caches the result: Assembly → Schema
internal static class ComponentSchemaRegistry
{
    private static readonly ConcurrentDictionary<Assembly, string?> _schemaCache = new();

    internal static string? GetSchema(Assembly assembly)
    {
        return _schemaCache.GetOrAdd(assembly, DiscoverSchema);
    }

    private static string? DiscoverSchema(Assembly assembly)
    {
        foreach (var type in assembly.GetTypes())
        {
            if (!typeof(DbContext).IsAssignableFrom(type))
                continue;

            var schemaField = type.GetField("SCHEMA", BindingFlags.Public | BindingFlags.Static);
            var schema = schemaField?.GetValue(null) as string;

            if (!string.IsNullOrWhiteSpace(schema))
                return schema;
        }
        return null;
    }
}

Example:

var passportAssembly = typeof(Passport).Assembly;  // Acsis.Dynaplex.Engines.Prism.Database
var schema = ComponentSchemaRegistry.GetSchema(passportAssembly);
// Returns: "prism" (discovered from PrismDb.SCHEMA constant)

2. ConfigureSchemaIsolation Extension

Located in: strata/core/src/Acsis.Dynaplex/DatabaseExtensions.cs

Purpose: Automatically exclude cross-schema entities from migrations

How it works:

  1. Iterates through all entities in the model
  2. For each entity, determines its "owning" schema via ComponentSchemaRegistry
  3. If entity belongs to different schema than current DbContext, marks it as excluded from migrations
  4. Optionally moves the entity to its correct schema if not already set
public static void ConfigureSchemaIsolation(this ModelBuilder modelBuilder, string contextSchema)
{
    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
    {
        var clrType = entityType.ClrType;
        string? entitySchema = entityType.GetSchema();

        if (clrType != null)
        {
            // Discover the entity's owning schema from its assembly
            var owningSchema = ComponentSchemaRegistry.GetSchema(clrType.Assembly);

            // If entity belongs to different component, move it to that schema
            if (!string.IsNullOrEmpty(owningSchema) && owningSchema != contextSchema)
            {
                entitySchema = owningSchema;
                entityType.SetSchema(owningSchema);
            }
        }

        // If entity belongs to different schema, exclude from migrations
        if (!string.IsNullOrEmpty(entitySchema) && entitySchema != contextSchema)
        {
            entityType.SetIsTableExcludedFromMigrations(true);
        }
    }
}

Key Points:

  • Call this LAST in OnModelCreating (after all entity configurations)
  • Entities are still in the model (for relationships and FK constraints)
  • EF Core generates correct FK constraints pointing to the proper schema.table
  • Migrations just won't attempt to create the excluded tables

3. Usage Pattern

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema(SCHEMA);
    base.OnModelCreating(modelBuilder);

    // ... your entity configurations ...

    // MUST be last!
    modelBuilder.ConfigureSchemaIsolation(SCHEMA);
}

How Schema Isolation Prevents Pollution

Before ConfigureSchemaIsolation:

-- CatalogDb migration tries to create:
CREATE TABLE catalog.passports (...);  -- ❌ WRONG SCHEMA!
CREATE TABLE catalog.items (...);      -- ✅ Correct

After ConfigureSchemaIsolation:

-- CatalogDb migration creates:
CREATE TABLE catalog.items (...);  -- ✅ Correct

-- FK constraint references existing table:
ALTER TABLE catalog.items
    ADD CONSTRAINT fk__catalog__items__prism__passports__id
    FOREIGN KEY (id) REFERENCES prism.passports(global_id);  -- ✅ Correct schema!

-- No attempt to create catalog.passports ✅

Prism Foundation

Role of Prism

Prism is the foundational infrastructure component providing:

  1. Passports - Global unique ID registry for all entities
  2. Platform Types - Type registry mapping PTIDs to entity types
  3. Identifiers - Alternative identifier system (barcodes, serial numbers, etc.)
  4. Attribute System - Dynamic attributes for entities
  5. Journal Tables - Centralized audit log for all components

All journal tables live in the Prism schema regardless of which component's data they track.

Reference: ADR-035: Prism Journal Tables

Passport Pattern

The Passport pattern provides global unique identifiers across all components:

// Prism.Database/Passport.cs
public class Passport
{
    public const string TABLE_NAME = "passports";

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid GlobalId { get; set; }  // UUIDv7

    public short PlatformTypeId { get; set; }  // Links to platform_types
}

Every entity that needs a global ID:

  1. Has Id property of type Guid
  2. Has PlatformTypeId property of type short
  3. Has a public const short PTID constant (see PTIDS in CoreData)
  4. Configures FK relationship to prism.passports

Automatic Passport Configuration

Use ConfigurePassportRelationships to auto-configure all entities:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema(SCHEMA);
    base.OnModelCreating(modelBuilder);

    // Configure external Passport reference
    modelBuilder.AddExternalReference<Passport>(Passport.TABLE_NAME, PrismDb.SCHEMA, p => p.GlobalId);

    // Automatically configure FK relationships for all entities with PlatformTypeId
    modelBuilder.ConfigurePassportRelationships(SCHEMA);

    // Schema isolation (must be last)
    modelBuilder.ConfigureSchemaIsolation(SCHEMA);
}

How ConfigurePassportRelationships works:

  1. Finds all entities in the current schema with PlatformTypeId property
  2. Automatically creates FK relationship: entity.Id → prism.passports.GlobalId
  3. Generates constraint name following convention: fk__{schema}__{table}__prism__passports__id
  4. Only configures entities in the current schema (skips external references)

Manual Alternative (if needed):

modelBuilder.Entity<Item>(b => {
    b.HasOne<Passport>()
        .WithOne()
        .HasForeignKey<Item>(x => x.Id)
        .OnDelete(DeleteBehavior.Restrict)
        .HasConstraintName($"fk__{SCHEMA}__{Item.TABLE_NAME}__{PrismDb.SCHEMA}__{Passport.TABLE_NAME}__id");
});

Cross-Component References

Referencing External Entities

When a component needs to reference entities from another component:

// In CatalogDb
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema(SCHEMA);
    base.OnModelCreating(modelBuilder);

    // Reference Passport from Prism
    modelBuilder.AddExternalReference<Passport>(
        Passport.TABLE_NAME,    // "passports"
        PrismDb.SCHEMA,         // "prism"
        p => p.GlobalId         // Primary key
    );

    // Reference Tenant from Identity
    modelBuilder.AddExternalReference<Tenant>(
        Tenant.TABLE_NAME,      // "tenants"
        IdentityDb.SCHEMA,      // "identity"
        t => t.Id               // Primary key
    );

    // ... rest of configuration ...
    modelBuilder.ConfigureSchemaIsolation(SCHEMA);
}

What AddExternalReference does:

  • Configures table name and schema
  • Configures primary key
  • Auto-maps key property to snake_case column name
  • Returns EntityTypeBuilder for additional configuration if needed

Pattern 2: Manual Configuration (Legacy)

modelBuilder.Entity<Passport>(b => {
    b.ToTable(Passport.TABLE_NAME, PrismDb.SCHEMA, t => t.ExcludeFromMigrations());
    b.HasKey(x => x.GlobalId);
    b.Property(x => x.GlobalId).HasColumnName("global_id");
});

Note: Manual configuration requires explicit ExcludeFromMigrations() call. With AddExternalReference, the subsequent ConfigureSchemaIsolation call handles exclusion automatically.

Project References

Database projects can reference other Database projects:

<!-- Acsis.Dynaplex.Engines.Catalog.Database.csproj -->
<ItemGroup>
  <!-- Required: Prism for Passport pattern -->
  <ProjectReference Include="$(PrismDatabase)" />

  <!-- Required: CoreData for primitives (PTIDS, etc.) -->
  <ProjectReference Include="$(CoreDataAbstractions)" />

  <!-- Optional: Other components if needed -->
  <ProjectReference Include="$(IdentityDatabase)" />
  <ProjectReference Include="$(SpatialDatabase)" />
</ItemGroup>

Guidelines:

  • Always reference Prism.Database (for Passport)
  • Always reference CoreData.Abstractions (for PTIDS and primitives)
  • Only reference other .Database projects if you need to query/relate to their entities
  • Avoid circular dependencies (use abstractions if needed for DTOs)

Migration Patterns

Creating Migrations

ALWAYS use the dplx CLI or database-migration-expert agent:

# Recommended: Use dplx CLI
dplx db migrations add -c catalog -n AddItemCategories

# Or use Claude slash command
/generate-migration

NEVER run dotnet ef migrations directly - the CLI ensures:

  • Correct DbContext is used
  • Proper project references
  • Migration naming conventions
  • Schema validation

Migration Ordering

Aspire AppHost ensures migrations run in dependency order:

// Prism MUST run first (owns passports table)
var prismMigrator = builder.AddProject<Prism_DbMigrator>("prism-migrator")
    .WaitFor(database);

// Other components depend on Prism
var catalogMigrator = builder.AddProject<Catalog_DbMigrator>("catalog-migrator")
    .WaitFor(prismMigrator);  // Blocks until Prism ready

var identityMigrator = builder.AddProject<Identity_DbMigrator>("identity-migrator")
    .WaitFor(prismMigrator);

Critical: Prism must migrate before any component that uses Passport pattern.

Migration Structure

Each migration should:

  • Only create/modify tables in its own schema
  • Reference external tables with proper schema prefix
  • Use lowercase_underscore naming for tables and columns
  • Follow FK constraint naming convention

FK Constraint Naming:

fk__{source_schema}__{source_table}__{target_schema}__{target_table}__{column}

Example:

ALTER TABLE catalog.items
    ADD CONSTRAINT fk__catalog__items__prism__passports__id
    FOREIGN KEY (id) REFERENCES prism.passports(global_id);

Best Practices

1. Always Call ConfigureSchemaIsolation

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // ... configurations ...

    // MUST be last line before OnModelCreatingPartial
    modelBuilder.ConfigureSchemaIsolation(SCHEMA);

    OnModelCreatingPartial(modelBuilder);
}

2. Use AddExternalReference for Cross-Component Entities

// ✅ Good: Clean, automatic exclusion
modelBuilder.AddExternalReference<Passport>(Passport.TABLE_NAME, PrismDb.SCHEMA, p => p.GlobalId);

// ❌ Avoid: Manual configuration (verbose, error-prone)
modelBuilder.Entity<Passport>(b => {
    b.ToTable(Passport.TABLE_NAME, PrismDb.SCHEMA, t => t.ExcludeFromMigrations());
    b.HasKey(x => x.GlobalId);
    // ...
});

3. Use ConfigurePassportRelationships for Auto-Configuration

// ✅ Good: Automatic FK configuration for all Passport entities
modelBuilder.ConfigurePassportRelationships(SCHEMA);

// ❌ Avoid: Manual configuration for each entity (unless you need custom behavior)
modelBuilder.Entity<Item>(b => {
    b.HasOne<Passport>()...
});

4. Define SCHEMA Constant in Every DbContext

// ✅ REQUIRED
public const string SCHEMA = "catalog";

// ❌ WRONG: Using string literal
modelBuilder.HasDefaultSchema("catalog");  // No registry entry!

5. Reference Database Projects, Not Abstractions

<!-- ✅ Correct: Reference Database project for entities -->
<ProjectReference Include="$(PrismDatabase)" />

<!-- ❌ Wrong: Abstractions don't have entities anymore -->
<ProjectReference Include="$(PrismAbstractions)" />

6. Add TenantId Indexes

// For multi-tenant entities, always add index on TenantId
modelBuilder.Entity<Item>().HasIndex(i => i.TenantId);
modelBuilder.Entity<ItemType>().HasIndex(it => it.TenantId);

7. Use Standard OnModelCreating Order

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // 1. Apply configurations from assembly (optional)
    modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());

    // 2. Set default schema
    modelBuilder.HasDefaultSchema(SCHEMA);

    // 3. Call base (applies tenant filtering)
    base.OnModelCreating(modelBuilder);

    // 4. Configure external references
    modelBuilder.AddExternalReference<Passport>(...);
    modelBuilder.AddExternalReference<Tenant>(...);

    // 5. Manual entity configurations (if needed)
    modelBuilder.Entity<Item>()...

    // 6. Auto-configure Passport relationships
    modelBuilder.ConfigurePassportRelationships(SCHEMA);

    // 7. Add indexes
    modelBuilder.Entity<Item>().HasIndex(i => i.TenantId);

    // 8. Schema isolation (MUST be last!)
    modelBuilder.ConfigureSchemaIsolation(SCHEMA);

    // 9. Partial method hook
    OnModelCreatingPartial(modelBuilder);
}

Common Pitfalls

1. Forgetting ConfigureSchemaIsolation

Symptom: Migrations try to create tables from other schemas

Solution:

// Add this as last line in OnModelCreating
modelBuilder.ConfigureSchemaIsolation(SCHEMA);

2. No SCHEMA Constant in DbContext

Symptom: ComponentSchemaRegistry can't discover schema, isolation doesn't work

Solution:

public const string SCHEMA = "catalog";  // REQUIRED!

3. Calling ConfigureSchemaIsolation Too Early

Symptom: External entities not properly configured yet

Solution: Always call ConfigureSchemaIsolation last in OnModelCreating

4. Referencing Abstractions Instead of Database Projects

Symptom: Build errors, missing entity types

Solution:

<!-- ✅ Correct -->
<ProjectReference Include="$(PrismDatabase)" />

<!-- ❌ Wrong -->
<ProjectReference Include="$(PrismAbstractions)" />

5. Manual Passport Configuration Without ExcludeFromMigrations

Symptom: Migrations try to create catalog.passports table

Solution: Use AddExternalReference instead of manual configuration, or add explicit exclusion:

modelBuilder.Entity<Passport>(b => {
    b.ToTable(Passport.TABLE_NAME, PrismDb.SCHEMA, t => t.ExcludeFromMigrations());
    // ...
});

6. Circular Database Project References

Symptom: Build fails with circular dependency error

Solution:

  • Review project references - Database projects should form a DAG (Directed Acyclic Graph)
  • Prism is at the root (no dependencies)
  • Other components depend on Prism, not each other (unless truly needed)
  • Use Abstractions for DTOs if you need shared types without database coupling

Troubleshooting

Problem: Migration tries to create tables from other schemas

Check:

  1. Is ConfigureSchemaIsolation(SCHEMA) called in OnModelCreating?
  2. Is it called last (before OnModelCreatingPartial)?
  3. Does your DbContext have public const string SCHEMA field?

Fix:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema(SCHEMA);
    base.OnModelCreating(modelBuilder);
    // ... configurations ...
    modelBuilder.ConfigureSchemaIsolation(SCHEMA);  // ← Add this!
}

Problem: FK constraint fails during migration

Check:

  1. Are you trying to reference an entity that doesn't exist yet?
  2. Is Prism migrator running before your component's migrator?
  3. Is the external entity properly configured with correct schema?

Fix:

// Ensure external references are configured
modelBuilder.AddExternalReference<Passport>(Passport.TABLE_NAME, PrismDb.SCHEMA, p => p.GlobalId);

// Check Aspire AppHost migration ordering
var catalogMigrator = builder.AddProject<Catalog_DbMigrator>("catalog-migrator")
    .WaitFor(prismMigrator);  // ← Ensure dependency

Problem: Entity not found in model

Check:

  1. Is the entity's assembly referenced in your Database project?
  2. Is the entity class public?
  3. Is there a DbSet<T> for the entity in the DbContext?

Fix:

// Add DbSet
public virtual DbSet<Passport> Passports { get; set; }

// Or configure without DbSet
modelBuilder.AddExternalReference<Passport>(Passport.TABLE_NAME, PrismDb.SCHEMA, p => p.GlobalId);

Problem: Passport FK constraint "missing primary key" error

Check:

  1. Is Passport entity configured with primary key?
  2. Is Passport excluded from migrations?
  3. Is AddExternalReference called before ConfigurePassportRelationships?

Fix:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema(SCHEMA);
    base.OnModelCreating(modelBuilder);

    // 1. Configure Passport FIRST
    modelBuilder.AddExternalReference<Passport>(Passport.TABLE_NAME, PrismDb.SCHEMA, p => p.GlobalId);

    // 2. Then configure relationships
    modelBuilder.ConfigurePassportRelationships(SCHEMA);

    // 3. Then schema isolation
    modelBuilder.ConfigureSchemaIsolation(SCHEMA);
}

Summary

The Dynaplex database architecture provides:

  1. Schema Isolation: Automatic prevention of cross-schema table creation via ConfigureSchemaIsolation
  2. Assembly-Based Discovery: ComponentSchemaRegistry maps assemblies to schemas using DbContext.SCHEMA constants
  3. Clean Separation: .Database projects separate from .Abstractions
  4. Prism Foundation: Centralized Passport, Platform Types, and Journal infrastructure
  5. Automatic Configuration: Helper methods reduce boilerplate and prevent errors
  6. Type Safety: Compile-time errors prevent schema pollution
  7. Multi-Tenancy: Automatic tenant filtering via DynaplexDbContext

The key insight: By combining assembly-based schema discovery with automatic migration exclusion, the system prevents schema pollution while maintaining clean FK relationships across component boundaries.

Code References

Key Classes

  • DynaplexDbContext: strata/core/src/Acsis.Dynaplex/DynaplexDbContext.cs
  • DatabaseExtensions: strata/core/src/Acsis.Dynaplex/DatabaseExtensions.cs
  • ComponentSchemaRegistry: strata/core/src/Acsis.Dynaplex/ComponentSchemaRegistry.cs
  • PrismDb: engines/prism/src/Acsis.Dynaplex.Engines.Prism.Database/PrismDb.cs
  • Passport: engines/prism/src/Acsis.Dynaplex.Engines.Prism.Database/Passport.cs

Example DbContexts

  • Prism (foundation): engines/prism/src/Acsis.Dynaplex.Engines.Prism.Database/PrismDb.cs
  • Identity (manual config): engines/identity/src/Acsis.Dynaplex.Engines.Identity.Database/IdentityDb.cs
  • Catalog (clean pattern): engines/catalog/src/Acsis.Dynaplex.Engines.Catalog.Database/CatalogDb.cs
  • Spatial (complex): engines/spatial/src/Acsis.Dynaplex.Engines.Spatial.Database/SpatialDb.cs