Skip to content

DI scope disposal (#7205) part 1: deliver row builder-context events to the test and raise OnDispose once per test #7381

Closed

Description

@thomhurst

Part 1 of #7205, split from #7328. That PR went over the issue-pr-loop rework budget (20 automated review rounds, and its latest review still had a blocking finding). Its branch issue-7205-di-scope-dispose (head b1a2ba27d2) has commits to reuse.

Scope

Deliver the OnDispose subscriptions that data sources make on the per-iteration TestBuilderContext to the test built from that row, and raise them once per test.

  • TestBuilderContext.ShareEventsWith (internal, lazy, like ShareStateBagWith).
  • In both the source-generated and reflection paths of TestBuilder, the class row's first fetch (fix(engine): reuse the first class-data fetch for the first test of a class row #7195) runs against its own context, and its events travel with UnclaimedClassRow to the test that takes it. A row handed back with Return keeps its events.
  • OnDispose is raised once per test in TestCoordinator's final cleanup, not once per attempt (AbstractExecutableTest.TryClaimOnDispose, TestOnDisposeRaiser.RaiseOnceAsync). This keeps retries working. Skipped, dependency-skipped, cancelled-before-start and circular-dependency-removed tests also raise it (TestScheduler, TestRunner).
  • Document the behavior change in ITestEvents.OnDispose, docs/docs/writing-tests/dependency-injection.md and the PR description, so it reaches the release notes. Handlers used to run once per attempt, before the instance was disposed. They now run once per test, after it.

Out of scope (separate issues)

Files

src/TUnit.Core/TestBuilderContext.cs, src/TUnit.Core/AbstractExecutableTest.cs, src/TUnit.Core/Interfaces/ITestEvents.cs, src/TUnit.Engine/Building/TestBuilder.cs (row-events plumbing only), src/TUnit.Engine/Services/TestExecution/TestCoordinator.cs, src/TUnit.Engine/Services/TestExecution/TestOnDisposeRaiser.cs (RaiseOnceAsync), src/TUnit.Engine/Scheduling/TestScheduler.cs, src/TUnit.Engine/Scheduling/TestRunner.cs, docs, and the matching tests/TUnit.TestProject/Bugs/_7205 and tests/TUnit.Engine.Tests/Issue7205Tests.cs cases.

Acceptance criteria

  • A class-level and a method-parameter DependencyInjectionDataSourceAttribute<TScope> scope is created once per test and disposed once, in source-generated and reflection modes. This includes [Repeat], [Retry] (the retry does not see a disposed scope) and [Skip] tests.
  • Tests that never reach the coordinator still dispose their scope once.
  • Keep the PR small: no session-level deferral machinery and no ownership changes.

Activity

  1. added
    bugSomething isn't working
    P1High: significant user-facing bug, fix soon
    on Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High: significant user-facing bug, fix soonbugSomething isn't workingin-progressWork is in progress

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions