{{ message }}
Repository navigation
feat: ask an interaction as an observable and run its handlers on a scheduler - #151
Merged
Merged
Conversation
glennawatson
enabled auto-merge (squash)
September 27, 2026 12:20
|
This was referenced Sep 27, 2026
glennawatson
added a commit
to reactiveui/ReactiveUI
that referenced
this pull request
Sep 27, 2026
## Summary **ReactiveUI now builds against ReactiveUI.Binding 8.6.0, which lets you ask an interaction as an observable again.** - `BindingVersion` in `Directory.Packages.props` is now `8.6.0`. - `IInteraction<TInput, TOutput>.Handle(TInput)` returns `IObservable<TOutput>`, as it did in ReactiveUI 24. - `Interaction<TInput, TOutput>.WhenHandled(TInput)` returns the question as a cold observable. - `new Interaction<TInput, TOutput>(handlerScheduler)` runs each handler on that scheduler, such as `RxSchedulers.MainThreadScheduler`. - `Interaction<TInput, TOutput>.Handle(TInput)` still returns `Task<TOutput>`, so code written against 25.0.0 keeps compiling. ## Why **Moving `Interaction` into ReactiveUI.Binding changed its API by accident in 25.0.0.** Code upgrading from ReactiveUI 24 that subscribed to `Handle`, used it in an observable chain, or passed a handler scheduler stopped compiling. ReactiveUI.Binding 8.6.0 (reactiveui/ReactiveUI.Binding.SourceGenerators#151) restores it. ## Breaking changes **None for code that uses or derives from `Interaction<TInput, TOutput>`.** A class that implements `IInteraction<TInput, TOutput>` itself must implement `Handle(TInput)` returning `IObservable<TOutput>`. Nothing in this repository does. ## How this was verified **Every Linux-runnable core test project passes on net10.0 against the released 8.6.0 packages.** - `ReactiveUI.Tests` (879), `ReactiveUI.Tests.Reactive` (881), `ReactiveUI.AOT.Tests` (39), `ReactiveUI.Testing.Tests` (57) and `ReactiveUI.Builder.Tests` (184) pass. - The Windows-only and device projects are left to CI. ## Checklist - [x] I have read the [Contribute guide](https://www.reactiveui.net/contribute/index.html) - [x] The PR title follows [Conventional Commits](https://www.conventionalcommits.org/) - [x] Tests cover this change, or the summary says why they do not - [x] New or changed public API has XML documentation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Summary
An interaction can be asked as an observable again, and its handlers can run on a scheduler.
IInteraction<TInput, TOutput>.Handle(TInput)returnsIObservable<TOutput>. Code that holds an interaction through the interface asks the question as it did in ReactiveUI 24.Interaction<,>implements it explicitly.Interaction<,>.WhenHandled(TInput)returns the question as a cold observable. Each subscription callsHandleonce, so a subclass that overridesHandlestill applies. It fails withUnhandledInteractionExceptionwhen no handler answers.new Interaction<TInput, TOutput>(handlerScheduler)runs each handler on that scheduler. Pass the main thread's scheduler so a dialog opens on the UI thread. A null scheduler, like the parameterless constructor, runs handlers on the calling thread.Interaction<,>.Handle(TInput)still returnsTask<TOutput>. Code written against the current release keeps compiling.Why
Moving
Interactioninto ReactiveUI.Binding changed its API by accident.HandlereturnedIObservable<TOutput>, andIInteractiondeclared it.HandlereturnTask<TOutput>, removed it fromIInteraction, and dropped the constructor that took a handler scheduler.Handle, used it in an observable chain, or passed a scheduler no longer compiled.Breaking changes
A class that implements
IInteraction<TInput, TOutput>itself must now implementHandle(TInput), returningIObservable<TOutput>.Interaction<,>is unaffected.How this was verified
Tests cover each new member, including a scheduler that holds handlers until it runs.
bindings/BindInteractionExamples.csrun and print their documented output.Notes for the reviewer
The change is in
Interactions/IInteraction.csandInteractions/Interaction.cs.PublicAPI.txtfiles are regenerated and only add the new members.WhenHandledgoes throughHandlerather than walking the handlers itself, so overrides are honoured. Disposing its subscription drops the answer, but a handler that is already running still finishes.Handletakes no cancellation token to stop it.Checklist