Skip to content

Implement Lifecycle Hooks (ToItem/FromItem) #16

@j-d-ha

Description

@j-d-ha

Priority: P1 - Critical
Tier: 2 - Single-Table Support
Effort: Large (12-18 hours)

Already In Codebase

  • No hook discovery or invocation is generated today.
  • src/LayeredCraft.DynamoMapper.Generators/Templates/Mapper.scriban currently generates:
    • ToItem: expression-bodied returning new Dictionary<string, AttributeValue>(...).SetXxx(...).SetXxx(...)
    • FromItem: expression-bodied returning new T { Prop = ..., ... }

Goal

Implement lifecycle hooks for both ToItem and FromItem so users can inject single-table logic (pk/sk composition, discriminator, TTL, attribute bags) without polluting domain models.

Hooks must be optional and compile away when not implemented.

Hook signatures (final)

Hooks are declared on the mapper class:

ToItem hooks

  • static partial void BeforeToItem(TSource source, Dictionary<string, AttributeValue> item);
  • static partial void AfterToItem(TSource source, Dictionary<string, AttributeValue> item);

FromItem hooks

  • static partial void BeforeFromItem(Dictionary<string, AttributeValue> item);
  • static partial void AfterFromItem(Dictionary<string, AttributeValue> item, ref TTarget entity);

Implementation notes

  • Update src/LayeredCraft.DynamoMapper.Generators/Templates/Mapper.scriban to block-bodied methods:

    • ToItem should create var item = new Dictionary<string, AttributeValue>(capacity);

    • Invoke BeforeToItem(source, item)

    • Perform all .SetXxx(...) work (either as statements or chained into item = item.Set...)

    • Invoke AfterToItem(source, item)

    • return item;

    • FromItem should:

      • Invoke BeforeFromItem(item)
      • Construct entity
      • Invoke AfterFromItem(item, ref entity)
      • return entity;
  • Decide hook emission strategy:

    • Recommended: always emit hook calls to partial methods, relying on the compiler to compile them away.
    • If you choose discovery/validation, add diagnostics for missing/wrong signatures (ties into Diagnostics issue).

Tests (must be part of this story)

Add verify tests demonstrating:

  • Hook calls are emitted in correct order.
  • Generated code compiles with:
    • no hook implementations
    • hook implementations present

Acceptance criteria

  • ToItem emits Before/After calls at correct points.
  • FromItem emits Before/After calls at correct points (After uses ref).
  • No hooks implemented -> no runtime overhead.
  • Snapshot tests cover both directions.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions