Skip to content

Add an async-aware Proceed extension for behaviors. - #273

Merged
kzu merged 1 commit into
mainfrom
dev/proceed-extension
Oct 5, 2026
Merged

kzu merged 1 commit into
mainfrom
dev/proceed-extension

Conversation

@kzu

@kzu kzu commented Oct 5, 2026

Copy link
Copy Markdown
Member

Behaviors see a Task or ValueTask as an ordinary return value. A reusable behavior cannot hard-code the result type, and Native AOT cannot look that result up with reflection.

IMethodInvocation.Proceed calls the rest of the pipeline and hands the behavior a settled ProceedOutcome:

return invocation.Proceed(next, async (outcome, again) =>
{
    if (outcome.Exception is IOException)
        return await again();

    return ProceedOutcome.FromValue((int)outcome.Value! + 1, outcome.Elapsed);
});

AsyncRegistry.Register<T>() installs the closed adapters for Task<T> and ValueTask<T>. The generator emits that call from the stunt static constructor. Non-generic Task and ValueTask adapters ship with the library.

Closes #263.

Tests

  • Synchronous values, exceptions, retries, ref outputs, and a callback that yields.
  • Faulted and canceled tasks keep their original outcome. A null task fails synchronously.
  • Two behaviors compose over one ValueTask<T>.
  • A class stunt reports a base exception and can adjust a base Task<int> (Castle/ProceedClassTests.cs).
  • Generated stunts contain AsyncRegistry.Register<int>() and AsyncRegistry.Register<string>().

@kzu kzu added the enhancement New feature or request label Oct 5, 2026
@kzu
kzu enabled auto-merge (rebase) October 5, 2026 07:14
@kzu
kzu merged commit 9eec4e3 into main Oct 5, 2026
6 checks passed
@kzu
kzu deleted the dev/proceed-extension branch October 5, 2026 07:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add an async-aware Proceed extension for behaviors

1 participant