Skip to content

DTDE Development Plan - Implementation Phases

← Back to Testing Strategy


1. Phase Overview

The DTDE development is organized into 5 phases, following an incremental delivery approach. Sharding is the primary focus, with temporal features as an optional add-on.

Phase 1: Foundation (4 weeks)
├── Core metadata models
├── Sharding strategies (property-agnostic)
├── Storage mode abstractions
└── Unit test infrastructure

Phase 2: EF Core Integration (4 weeks)
├── DbContext options extension
├── Fluent API extensions (ShardBy, WithStorageMode)
├── Table sharding implementation
└── Integration tests

Phase 3: Query Engine (5 weeks)
├── Shard query planner
├── Parallel query executor
├── Result merger
└── Performance benchmarks

Phase 4: Advanced Features (4 weeks)
├── Database sharding (multi-DB)
├── Manual table support (sqlproj)
├── Optional temporal module
└── Consistency handling

Phase 5: Production Readiness (3 weeks)
├── Documentation
├── Performance optimization
├── NuGet packaging
└── Sample applications

Total: ~20 weeks (5 months)

2. Phase 1: Foundation (Weeks 1-4)

2.1 Objectives

  • Establish core domain models with property-agnostic design
  • Create sharding strategy infrastructure
  • Implement storage mode abstractions
  • Achieve 85% test coverage on core components

2.2 Deliverables

Week Deliverable Status
1 Project structure, CI/CD pipeline 🔲
1 PropertyMetadata, EntityMetadata classes 🔲
2 ShardingConfiguration, ShardStorageMode enum 🔲
2 ShardMetadata with expression-based predicates 🔲
3 IShardingStrategy interface and implementations 🔲
3 PropertyBasedStrategy, DateRangeStrategy, HashStrategy 🔲
4 IShardStorage interface and TableShardStorage 🔲
4 Unit tests for all core components 🔲

2.3 Acceptance Criteria

Feature: Sharding Configuration

  Scenario: Configure entity with property-based sharding
    Given an entity type "Customer" with property "Region"
    When I configure sharding using ShardBy(c => c.Region)
    Then the ShardingConfiguration should use PropertyValue strategy
    And the shard key expression should reference "Region"

  Scenario: Configure entity with date-based sharding
    Given an entity type "Order" with property "OrderDate"
    When I configure sharding using ShardByDate(o => o.OrderDate, DateShardInterval.Year)
    Then the ShardingConfiguration should use DateRange strategy
    And shard tables should be named "Orders_2023", "Orders_2024", etc.

  Scenario: Resolve shards by property value
    Given shards configured for regions "EU", "US", "APAC"
    When I resolve shards for Region = "US"
    Then only "Customers_US" shard should be returned

2.4 Technical Tasks

[ ] Create solution structure
    src/
    ├── Dtde.Core/
    ├── Dtde.EntityFramework/
    └── Dtde.Abstractions/
    tests/
    ├── Dtde.Core.Tests/
    └── Dtde.EntityFramework.Tests/

[ ] Configure Directory.Build.props
    - .NET 8.0 target
    - Nullable enabled
    - Implicit usings
    - Code analysis rules

[ ] Implement PropertyMetadata
    - PropertyName, PropertyType, ColumnName
    - Compiled getters/setters

[ ] Implement ShardingConfiguration
    - ShardKeyExpression (LambdaExpression)
    - StrategyType enum
    - StorageMode enum

[ ] Implement EntityMetadata
    - ClrType, TableName, SchemaName
    - PrimaryKey, Sharding (required)
    - TemporalConfig (optional)

[ ] Implement ShardMetadata
    - ShardId, Name
    - TableName or ConnectionString
    - ShardPredicate (LambdaExpression)

[ ] Implement IShardingStrategy
    - GetShardKey method
    - GetTargetShards method

[ ] Implement PropertyBasedStrategy
    - Simple property value matching
    - Equal/In operators

[ ] Implement DateRangeStrategy
    - Year/Quarter/Month intervals
    - Date range intersection

[ ] Implement HashStrategy
    - Consistent hashing
    - Configurable shard count

[ ] Implement IShardStorage
    - TableShardStorage (same DB)
    - GetShardContext method

[ ] Implement MetadataRegistry
    - Entity registration
    - Shard registration
    - Validation

[ ] Write unit tests (85% coverage)

3. Phase 2: EF Core Integration (Weeks 5-8)

3.1 Objectives

  • Integrate with EF Core service pipeline
  • Implement Fluent API extensions (sharding-first)
  • Implement table sharding (single database)
  • Enable simple queries to work end-to-end

3.2 Deliverables

Week Deliverable Status
5 DtdeOptionsExtension for DbContext 🔲
5 DtdeOptionsBuilder with fluent configuration 🔲
6 ShardBy(), WithStorageMode() extensions 🔲
6 DtdeDbContext base class 🔲
7 Table name rewriting interceptor 🔲
7 ShardQueryInterceptor for query routing 🔲
8 Model finalizer for metadata extraction 🔲
8 Integration tests with table sharding 🔲

3.3 Acceptance Criteria

Feature: EF Core Integration

  Scenario: Configure DbContext with DTDE
    Given a DbContext class inheriting from DtdeDbContext
    When I call UseDtde() in OnConfiguring
    Then DTDE services should be registered
    And queries should be intercepted by DTDE

  Scenario: Configure entity with Fluent API
    Given an entity "Customer" in OnModelCreating
    When I call entity.ShardBy(c => c.Region)
    And I call .WithStorageMode(ShardStorageMode.Tables)
    Then EntityMetadata should be created from model
    And tables should be named Customers_EU, Customers_US, etc.

  Scenario: Query routes to single shard
    Given a sharded entity "Customer" with Region = "US"
    When I query db.Customers.Where(c => c.Region == "US").ToListAsync()
    Then only Customers_US table should be queried
    And results should be returned

3.4 Technical Tasks

[ ] Implement DtdeOptionsExtension
    - Implement IDbContextOptionsExtension
    - Register DTDE services
    - Configure service replacements

[ ] Implement DtdeOptionsBuilder
    - ConfigureEntity<T> method
    - SetMaxParallelShards method
    - EnableDiagnostics method

[ ] Implement Fluent API extensions
    - ShardBy<TEntity> extension
    - ShardByDate<TEntity> extension
    - ShardByHash<TEntity> extension
    - WithStorageMode extension

[ ] Implement DtdeDbContext
    - Shard context management
    - Dynamic model caching

[ ] Implement ShardQueryInterceptor
    - Detect shardable queries
    - Route to correct shard table(s)
    - Rewrite table names

[ ] Implement DtdeModelFinalizer
    - Read model annotations
    - Build EntityMetadata from model
    - Register with MetadataRegistry

[ ] Write integration tests (table sharding)
    - Single shard queries
    - Multi-shard queries
    - Insert routing

4. Phase 3: Query Engine (Weeks 9-13)

4.1 Objectives

  • Implement full distributed query execution
  • Support parallel shard queries
  • Implement global ordering and pagination
  • Achieve performance targets

4.2 Deliverables

Week Deliverable Status
9 DtdeQueryDefinition model 🔲
9 ShardQueryPlan and ShardQuery 🔲
10 IShardQueryPlanner implementation 🔲
10 Predicate extraction for shard resolution 🔲
11 IDtdeQueryExecutor implementation 🔲
11 Parallel execution with bounded concurrency 🔲
12 IResultMerger implementation 🔲
12 Global ordering and pagination 🔲
13 Performance benchmarks 🔲
13 Multi-shard integration tests 🔲

4.3 Acceptance Criteria

Feature: Distributed Query Execution

  Scenario: Query resolves to single shard
    Given data distributed across 4 quarterly shards
    When I query ValidAt(2024-06-15)
    Then only Shard2024Q2 should be queried
    And results should be returned within 100ms

  Scenario: Query resolves to multiple shards
    Given data distributed across 4 quarterly shards
    When I query ValidBetween(2024-03-01, 2024-07-01)
    Then Shard2024Q1 and Shard2024Q2 should be queried
    And results should be merged correctly

  Scenario: Pagination applies globally
    Given 1000 contracts across 4 shards
    When I query OrderBy(ContractNumber).Skip(10).Take(10)
    Then 10 results should be returned
    And they should be globally sorted by ContractNumber

  Scenario: Performance targets met
    Given 1 million contracts across 4 shards
    When I query ValidAt(date).Take(100)
    Then results should be returned within 200ms

4.4 Technical Tasks

[ ] Implement DtdeQueryDefinition
    - Capture expression tree
    - Extracted shard key predicates
    - Ordering specifications

[ ] Implement ShardQueryPlanner
    - Resolve target shards from predicates
    - Build per-shard query expressions
    - Calculate per-shard take limits

[ ] Implement ParallelQueryExecutor
    - Create per-shard DbContext instances
    - Execute queries in parallel
    - Use SemaphoreSlim for bounded concurrency

[ ] Implement ResultMerger
    - Concatenate shard results
    - Apply global ordering
    - Apply global Skip/Take

[ ] Implement diagnostics
    - ShardResolvedEvent
    - QueryExecutedEvent
    - Per-shard timing

[ ] Create benchmark suite
    - Single shard queries
    - Multi-shard queries
    - Pagination queries
    - Large result set handling

[ ] Write multi-shard integration tests

5. Phase 4: Advanced Features (Weeks 14-17)

5.1 Objectives

  • Implement database sharding (multiple databases)
  • Support manual tables (sqlproj scenarios)
  • Add optional temporal module
  • Handle cross-shard consistency

5.2 Deliverables

Week Deliverable Status
14 DatabaseShardStorage implementation 🔲
14 Multi-database connection management 🔲
15 ManualShardStorage implementation 🔲
15 Pre-created table routing 🔲
16 Optional ValidAt(), AllVersions() extensions 🔲
16 HasTemporalValidity() Fluent API 🔲
17 SaveChangesWithVersioningAsync() method 🔲
17 Cross-shard write consistency 🔲

5.3 Acceptance Criteria

Feature: Database Sharding

  Scenario: Route queries to separate databases
    Given Customers_EU on server1 and Customers_US on server2
    When I query db.Customers.Where(c => c.Region == "US").ToListAsync()
    Then only server2 should be connected
    And results from Customers table returned

  Scenario: Manual table configuration
    Given pre-created tables Orders_2023 and Orders_2024
    When I configure UseManualSharding with table predicates
    Then queries should route based on predicates
    And no migrations should be generated

Feature: Optional Temporal Module

  Scenario: Standard update without versioning
    Given a sharded entity without temporal configuration
    When I update and call SaveChangesAsync()
    Then standard EF update should occur (no version bump)

  Scenario: Temporal versioning (opt-in)
    Given a sharded entity WITH temporal configuration
    When I update and call SaveChangesWithVersioningAsync()
    Then old version should be closed (ValidTo = now)
    And new version should be created (ValidFrom = now)

  Scenario: ValidAt query on temporal entity
    Given a temporal entity with multiple versions
    When I query db.Contracts.ValidAt(date).ToListAsync()
    Then only versions valid at that date should be returned

5.4 Technical Tasks

[ ] Implement DatabaseShardStorage
    - Connection string per shard
    - DbContext factory per database
    - Connection pooling

[ ] Implement ManualShardStorage
    - Pre-defined table mappings
    - Predicate-based routing
    - MigrationsEnabled = false support

[ ] Implement temporal query extensions
    - ValidAt<TEntity> method
    - AllVersions<TEntity> method
    - ValidBetween<TEntity> method

[ ] Implement HasTemporalValidity Fluent API
    - Property-agnostic start/end
    - Open-ended validity support

[ ] Implement SaveChangesWithVersioningAsync
    - Explicit opt-in for versioning
    - Close old version + create new
    - Cross-shard version bump

[ ] Implement cross-shard write handling
    - Transaction coordination
    - Best-effort consistency
    - Diagnostic events

[ ] Write advanced integration tests

6. Phase 5: Production Readiness (Weeks 18-20)

6.1 Objectives

  • Complete documentation
  • Optimize performance bottlenecks
  • Package for NuGet
  • Create sample applications

6.2 Deliverables

Week Deliverable Status
18 API documentation (XML comments) 🔲
18 README and getting started guide 🔲
19 Performance profiling and optimization 🔲
19 Connection pool optimization 🔲
20 NuGet package configuration 🔲
20 Sample web API application 🔲

6.3 Acceptance Criteria

Feature: Production Readiness

  Scenario: NuGet package installation
    Given a new .NET 8 project
    When I run "dotnet add package Dtde.EntityFramework"
    Then the package should install successfully
    And all dependencies should resolve

  Scenario: Quick start works
    Given the README getting started guide
    When I follow the steps to configure DTDE
    Then I should have a working temporal, sharded application

  Scenario: Performance targets met
    Given the benchmark suite
    When I run all benchmarks
    Then no benchmark should exceed the acceptable threshold

6.4 Technical Tasks

[ ] Complete API documentation
    - XML comments on all public types
    - Examples in remarks
    - Cross-references

[ ] Write README.md
    - Quick start guide
    - Configuration reference
    - FAQ

[ ] Write architecture documentation
    - Component diagrams
    - Flow diagrams
    - Decision records

[ ] Performance optimization
    - Expression caching
    - Connection pooling
    - Compiled delegates

[ ] Configure NuGet packaging
    - Package metadata
    - Symbol packages
    - Source link

[ ] Create sample application
    - Contract management API
    - Multi-shard setup
    - Docker compose

7. Risk Mitigation

Risk Impact Likelihood Mitigation
EF Core internal API changes High Medium Abstract integration points, maintain compatibility tests
Performance not meeting targets High Medium Early benchmarking, profiling in Phase 3
Cross-shard consistency issues High Medium Implement outbox pattern, comprehensive testing
Complex expression trees failing Medium Medium Extensive expression rewriter testing, fallback paths
Integration complexity Medium Low Incremental delivery, early integration tests

8. Resource Requirements

8.1 Development Approach

This project is developed as a solo endeavor, combining all roles:

Responsibility Phases Notes
Architecture & Core Development All phases Primary focus
EF Core Integration Phases 2-4 Deep integration work
Testing & QA All phases Continuous quality focus
Documentation Phase 5 Final polish

8.2 Infrastructure

Resource Purpose
SQL Server instances (3+) Integration/benchmark testing
CI/CD pipeline Build, test, package automation
GitHub repository Source control, issue tracking
NuGet.org account Package publishing

9. Milestone Summary

Milestone Week Key Deliverables
M1: Foundation Complete 4 Core models, metadata, strategies
M2: Single-Shard Works 8 EF Core integration, temporal queries
M3: Multi-Shard Works 13 Distributed queries, pagination
M4: Updates Work 17 Versioning, cross-shard writes
M5: Release Ready 20 Documentation, NuGet package

Next Steps

Return to the Overview or explore the Guides for practical tutorials.