Skip to content

Define generator-targeted graph metadata hooks and constructor-selection contract #125

Description

@cwinland

Docs reference: docs/roadmap/generator-roadmap.md

This issue defines the constructor-selection contract that generated graph or harness code can target without re-implementing FastMoq runtime constructor matching.

The goal of this slice is to name and bound the public request and resolved-plan contract for constructor selection, then map that contract back to the current runtime path. Generated code should describe constructor intent and consume stable resolved metadata; runtime code should continue to own reflection, constructor matching, and execution behavior.

Preferred contract direction for this issue:

  • Public request model: InstanceConstructionRequest
  • Public resolved read model: InstanceConstructionPlan
  • Public parameter read model: InstanceConstructionParameterPlan
  • Public parameter-source enum: InstanceConstructionParameterSource
  • Preferred public entry point on Mocker: InstanceConstructionPlan CreateConstructionPlan(InstanceConstructionRequest request)

Final intended public surface for this issue:

  • InstanceConstructionRequest
  • Type RequestedType
  • Type?[]? ConstructorParameterTypes
  • bool? PublicOnly
  • OptionalParameterResolutionMode OptionalParameterResolution
  • ConstructorAmbiguityBehavior ConstructorAmbiguityBehavior
  • InstanceConstructionPlan
  • Type RequestedType
  • Type ResolvedType
  • bool UsedNonPublicConstructor
  • bool UsedPreferredConstructorAttribute
  • bool UsedAmbiguityFallback
  • IReadOnlyList<InstanceConstructionParameterPlan> Parameters
  • InstanceConstructionParameterPlan
  • string Name
  • Type ParameterType
  • int Position
  • bool IsOptional
  • OptionalParameterResolutionMode OptionalParameterResolution
  • object? ServiceKey
  • InstanceConstructionParameterSource Source
  • InstanceConstructionParameterSource
  • CustomRegistration
  • KnownType
  • KeyedService
  • AutoMock
  • OptionalDefault
  • TypeDefault

Contract boundary for this slice:

  • The public request model captures constructor-selection intent only.
  • The public resolved plan exposes stable constructor-selection output only.
  • Generated code should target this contract directly instead of reproducing reflection-based constructor matching logic.
  • The runtime implementation should continue to map through current constructor-selection behavior such as CreateInstance(...), CreateInstanceByType(...), preferred-constructor handling, optional-parameter handling, keyed-resolution handling, and constructor-history evidence.
  • Existing public diagnostics surfaces such as ConstructorHistory and ConstructorModel remain available for reflection-heavy evidence and should not be demoted.
  • ConstructedByMocker is deferred out of this first-slice contract because the current runtime parameter path does not recursively construct dependency parameters as a distinct category; current concrete-parameter outcomes remain AutoMock or TypeDefault unless a custom or known registration applies.

Public-surface guard:

  • This issue must not make any existing public type, member, or public runtime behavior less accessible in order to make the new contract cleaner.
  • Existing public diagnostics, model types, creation APIs, and current public reflection-metadata or framework-style resolution behavior remain part of the compatibility boundary.
  • In particular, if FastMoq already publicly resolves reflection metadata such as ConstructorInfo, MemberInfo, or ParameterInfo through normal runtime flows, this issue should not rely on hiding or downgrading that behavior.

Acceptance checklist:

  • The constructor-selection contract is explicit enough for generated code to target directly.
  • One public request type and one public resolved-plan shape are named and scoped.
  • The issue names the intended public properties for InstanceConstructionRequest, InstanceConstructionPlan, and InstanceConstructionParameterPlan.
  • The issue names the intended first-slice enum members for InstanceConstructionParameterSource.
  • The contract covers exact constructor choice, visibility scope, optional-parameter handling, ambiguity behavior, and keyed or special dependency metadata.
  • The handoff between generated code and runtime code is explicit so emitted output does not repeat reflection-based constructor matching.
  • The contract is mapped to current runtime surfaces such as CreateInstanceByType(...), constructor flags, preferred-constructor handling, keyed-resolution behavior, and constructor history.
  • The plan preserves existing public accessibility and does not demote current public surface or current public runtime behavior.
  • Parity coverage is defined for exact selection, explicit parameterless selection, public-only versus non-public fallback, optional/default behavior, ambiguity handling, preferred constructors, and keyed or special dependency cases.
  • Non-goals stay explicit: this issue does not define provider-specific setup or verification semantics.

Non-goals and follow-on boundaries:

  • This issue does not define provider-specific setup or verification semantics.
  • This issue does not commit to a new executable-plan API such as CreateInstance(InstanceConstructionPlan plan).
  • This issue does not add new public reflection-heavy contract fields such as raw ConstructorInfo, ParameterInfo, or executable argument values to the new plan types in this slice.
  • Existing public diagnostics types that already expose reflection-heavy evidence remain public; they are preserved rather than duplicated in the new contract.
  • The graph and harness MVP stays in #122.
  • Scenario scaffolding stays in #126.
  • Package detection and helper normalization stay in later slices such as #127 and #134.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-designPublic API and design evaluation workenhancementNew feature or requestpriorityThis should be worked on before others

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions