From de19359eee8e5aaf6dc41ae131ee25aa41f8a649 Mon Sep 17 00:00:00 2001 From: Chris Pulman Date: Sat, 31 Jan 2026 22:24:04 +0000 Subject: [PATCH 1/2] Add WithMessageBus and TaskPool schedulers Introduce a unified WithMessageBus API (WithMessageBus(), WithMessageBus(IMessageBus), WithMessageBus(Action)) and implement message-bus registration in ReactiveUIBuilder. Add RegisterConstantViewModel() to register constant VM instances. Configure TaskPoolScheduler.Default via WithTaskPoolScheduler in multiple platform builder extensions (AndroidX, Blazor, Maui, WinUI, WinForms, WPF) instead of platform registration files. Remove direct RxSchedulers assignments from several platform Registrations to centralize scheduler setup. Update mixins, tests, examples and project files to use the new APIs and clean up minor issues (usings, default expressions, project metadata, and API approval baselines). --- .../AndroidXReactiveUIBuilderExtensions.cs | 1 + .../BlazorReactiveUIBuilderExtensions.cs | 19 ++++++++++ src/ReactiveUI.Blazor/Registrations.cs | 3 -- .../MauiReactiveUIBuilderExtensions.cs | 1 + src/ReactiveUI.Maui/Registrations.cs | 6 ---- .../WinUIReactiveUIBuilderExtensions.cs | 1 + .../WinFormsReactiveUIBuilderExtensions.cs | 1 + src/ReactiveUI.Winforms/Registrations.cs | 1 - .../Builder/WpfReactiveUIBuilderExtensions.cs | 3 +- src/ReactiveUI.Wpf/Registrations.cs | 7 ---- src/ReactiveUI/Builder/IReactiveUIBuilder.cs | 20 ++++++++++- src/ReactiveUI/Builder/ReactiveUIBuilder.cs | 36 +++++++++++++++---- src/ReactiveUI/Mixins/BuilderMixins.cs | 36 +++++++++++++++++-- .../Program.cs | 10 +----- .../ReactiveUI.Builder.BlazorServer.csproj | 1 + .../Services/FileJsonSuspensionDriver.cs | 3 +- .../Services/ReactiveUiAppHostedService.cs | 2 -- .../Views/LobbyView.razor.cs | 1 - .../ReactiveUI.Builder.WpfApp/App.xaml.cs | 9 ++--- .../Models/RoomEventMessage.cs | 4 ++- .../ReactiveUI.Builder.WpfApp.csproj | 8 +++++ .../BlazorReactiveUIBuilderExtensionsTests.cs | 18 ++++++++-- .../Mixins/BuilderMixinsTests.cs | 4 +-- ...alTests.ReactiveUI.DotNet10_0.verified.txt | 15 ++++++-- ...valTests.ReactiveUI.DotNet8_0.verified.txt | 15 ++++++-- ...valTests.ReactiveUI.DotNet9_0.verified.txt | 15 ++++++-- 26 files changed, 177 insertions(+), 63 deletions(-) diff --git a/src/ReactiveUI.AndroidX/Builder/AndroidXReactiveUIBuilderExtensions.cs b/src/ReactiveUI.AndroidX/Builder/AndroidXReactiveUIBuilderExtensions.cs index 888d25e65c..db2aec63a6 100644 --- a/src/ReactiveUI.AndroidX/Builder/AndroidXReactiveUIBuilderExtensions.cs +++ b/src/ReactiveUI.AndroidX/Builder/AndroidXReactiveUIBuilderExtensions.cs @@ -34,6 +34,7 @@ public static IReactiveUIBuilder WithAndroidX(this IReactiveUIBuilder builder) return builder .WithMainThreadScheduler(HandlerScheduler.MainThreadScheduler) + .WithTaskPoolScheduler(TaskPoolScheduler.Default) .WithPlatformModule(); } diff --git a/src/ReactiveUI.Blazor/Builder/BlazorReactiveUIBuilderExtensions.cs b/src/ReactiveUI.Blazor/Builder/BlazorReactiveUIBuilderExtensions.cs index 976d08c7a6..1ea780e358 100644 --- a/src/ReactiveUI.Blazor/Builder/BlazorReactiveUIBuilderExtensions.cs +++ b/src/ReactiveUI.Blazor/Builder/BlazorReactiveUIBuilderExtensions.cs @@ -40,6 +40,25 @@ public static IReactiveUIBuilder WithBlazor(this IReactiveUIBuilder builder) return builder .WithBlazorScheduler() + .WithTaskPoolScheduler(TaskPoolScheduler.Default) + .WithPlatformModule(); + } + + /// + /// Configures ReactiveUI for Blazor platform with appropriate schedulers. + /// + /// The builder instance. + /// The builder instance for chaining. + public static IReactiveUIBuilder WithBlazorWasm(this IReactiveUIBuilder builder) + { + if (builder is null) + { + throw new ArgumentNullException(nameof(builder)); + } + + return builder + .WithBlazorWasmScheduler() + .WithTaskPoolScheduler(TaskPoolScheduler.Default) .WithPlatformModule(); } diff --git a/src/ReactiveUI.Blazor/Registrations.cs b/src/ReactiveUI.Blazor/Registrations.cs index 7161dbdb8b..7dc94ceb87 100644 --- a/src/ReactiveUI.Blazor/Registrations.cs +++ b/src/ReactiveUI.Blazor/Registrations.cs @@ -46,8 +46,5 @@ public void Register(IRegistrar registrar) { PlatformEnlightenmentProvider.Current.EnableWasm(); } - - RxSchedulers.TaskpoolScheduler = TaskPoolScheduler.Default; - RxSchedulers.MainThreadScheduler = CurrentThreadScheduler.Instance; } } diff --git a/src/ReactiveUI.Maui/Builder/MauiReactiveUIBuilderExtensions.cs b/src/ReactiveUI.Maui/Builder/MauiReactiveUIBuilderExtensions.cs index 7945f71db1..56f94a0ad8 100644 --- a/src/ReactiveUI.Maui/Builder/MauiReactiveUIBuilderExtensions.cs +++ b/src/ReactiveUI.Maui/Builder/MauiReactiveUIBuilderExtensions.cs @@ -70,6 +70,7 @@ public static IReactiveUIBuilder WithMaui(this IReactiveUIBuilder builder, IDisp return builder .WithMauiScheduler(dispatcher) + .WithTaskPoolScheduler(TaskPoolScheduler.Default) .WithPlatformModule() .WithPlatformServices(); } diff --git a/src/ReactiveUI.Maui/Registrations.cs b/src/ReactiveUI.Maui/Registrations.cs index f35817b8b1..3267b0a66f 100644 --- a/src/ReactiveUI.Maui/Registrations.cs +++ b/src/ReactiveUI.Maui/Registrations.cs @@ -36,12 +36,6 @@ public void Register(IRegistrar registrar) registrar.RegisterConstant(static () => new AutoDataTemplateBindingHook()); registrar.RegisterConstant(static () => new ComponentModelFallbackConverter()); - if (!ModeDetector.InUnitTestRunner()) - { - RxSchedulers.MainThreadScheduler = new WaitForDispatcherScheduler(static () => DispatcherQueueScheduler.Current); - RxSchedulers.TaskpoolScheduler = TaskPoolScheduler.Default; - } - RxSchedulers.SuppressViewCommandBindingMessage = true; #endif } diff --git a/src/ReactiveUI.WinUI/Builder/WinUIReactiveUIBuilderExtensions.cs b/src/ReactiveUI.WinUI/Builder/WinUIReactiveUIBuilderExtensions.cs index 8b4a34c89e..96b035730a 100644 --- a/src/ReactiveUI.WinUI/Builder/WinUIReactiveUIBuilderExtensions.cs +++ b/src/ReactiveUI.WinUI/Builder/WinUIReactiveUIBuilderExtensions.cs @@ -29,6 +29,7 @@ public static IReactiveUIBuilder WithWinUI(this IReactiveUIBuilder builder) return builder .WithWinUIScheduler() + .WithTaskPoolScheduler(TaskPoolScheduler.Default) .WithPlatformModule(); } diff --git a/src/ReactiveUI.Winforms/Builder/WinFormsReactiveUIBuilderExtensions.cs b/src/ReactiveUI.Winforms/Builder/WinFormsReactiveUIBuilderExtensions.cs index 6c45a0b3bc..285c8380e6 100644 --- a/src/ReactiveUI.Winforms/Builder/WinFormsReactiveUIBuilderExtensions.cs +++ b/src/ReactiveUI.Winforms/Builder/WinFormsReactiveUIBuilderExtensions.cs @@ -33,6 +33,7 @@ public static IReactiveUIBuilder WithWinForms(this IReactiveUIBuilder builder) return builder .WithMainThreadScheduler(WinFormsMainThreadScheduler) + .WithTaskPoolScheduler(TaskPoolScheduler.Default) .WithPlatformModule(); } diff --git a/src/ReactiveUI.Winforms/Registrations.cs b/src/ReactiveUI.Winforms/Registrations.cs index cdb3e49068..47d813b439 100644 --- a/src/ReactiveUI.Winforms/Registrations.cs +++ b/src/ReactiveUI.Winforms/Registrations.cs @@ -31,7 +31,6 @@ public void Register(IRegistrar registrar) if (!ModeDetector.InUnitTestRunner()) { WindowsFormsSynchronizationContext.AutoInstall = true; - RxSchedulers.MainThreadScheduler = new WaitForDispatcherScheduler(static () => new SynchronizationContextScheduler(new WindowsFormsSynchronizationContext())); } } } diff --git a/src/ReactiveUI.Wpf/Builder/WpfReactiveUIBuilderExtensions.cs b/src/ReactiveUI.Wpf/Builder/WpfReactiveUIBuilderExtensions.cs index 8f9c6b7583..57924c3de5 100644 --- a/src/ReactiveUI.Wpf/Builder/WpfReactiveUIBuilderExtensions.cs +++ b/src/ReactiveUI.Wpf/Builder/WpfReactiveUIBuilderExtensions.cs @@ -32,7 +32,8 @@ public static IReactiveUIBuilder WithWpf(this IReactiveUIBuilder builder) return builder .WithPlatformModule() .WithPlatformServices() - .WithWpfScheduler(); + .WithWpfScheduler() + .WithTaskPoolScheduler(TaskPoolScheduler.Default); } /// diff --git a/src/ReactiveUI.Wpf/Registrations.cs b/src/ReactiveUI.Wpf/Registrations.cs index 81bed3f43e..ed4234ccce 100644 --- a/src/ReactiveUI.Wpf/Registrations.cs +++ b/src/ReactiveUI.Wpf/Registrations.cs @@ -29,13 +29,6 @@ public void Register(IRegistrar registrar) registrar.RegisterConstant(static () => new AutoDataTemplateBindingHook()); registrar.RegisterConstant(static () => new ComponentModelFallbackConverter()); - if (!ModeDetector.InUnitTestRunner()) - { - // NB: On .NET Core, trying to touch DispatcherScheduler blows up :cry: - RxSchedulers.MainThreadScheduler = new WaitForDispatcherScheduler(static () => DispatcherScheduler.Current); - RxSchedulers.TaskpoolScheduler = TaskPoolScheduler.Default; - } - RxSchedulers.SuppressViewCommandBindingMessage = true; } } diff --git a/src/ReactiveUI/Builder/IReactiveUIBuilder.cs b/src/ReactiveUI/Builder/IReactiveUIBuilder.cs index de16ecf61f..bf469adb9a 100644 --- a/src/ReactiveUI/Builder/IReactiveUIBuilder.cs +++ b/src/ReactiveUI/Builder/IReactiveUIBuilder.cs @@ -38,12 +38,18 @@ namespace ReactiveUI.Builder; /// public interface IReactiveUIBuilder : IAppBuilder { + /// + /// Configures the message bus. + /// + /// The builder instance for chaining. + IReactiveUIBuilder WithMessageBus(); + /// /// Configures the message bus. /// /// A delegate to configure the message bus. /// The builder instance for chaining. - IReactiveUIBuilder ConfigureMessageBus(Action configure); + IReactiveUIBuilder WithMessageBus(Action configure); /// /// Registers a custom message bus instance. @@ -121,6 +127,18 @@ IReactiveUIBuilder RegisterView() IReactiveUIBuilder RegisterViewModel() where TViewModel : class, IReactiveObject, new(); + /// + /// Registers a constant instance of the specified view model type for use in the reactive UI builder. + /// + /// The registered view model instance is created once using its parameterless constructor and + /// reused for all requests. Use this method when the view model does not require per-request state or + /// dependencies. + /// The type of the view model to register. Must be a reference type that implements IReactiveObject and has a + /// parameterless constructor. + /// The current instance of the reactive UI builder, enabling method chaining. + IReactiveUIBuilder RegisterConstantViewModel() + where TViewModel : class, IReactiveObject, new(); + /// /// Withes the main thread scheduler. /// diff --git a/src/ReactiveUI/Builder/ReactiveUIBuilder.cs b/src/ReactiveUI/Builder/ReactiveUIBuilder.cs index d0d94fe2d1..405474ed7a 100644 --- a/src/ReactiveUI/Builder/ReactiveUIBuilder.cs +++ b/src/ReactiveUI/Builder/ReactiveUIBuilder.cs @@ -272,19 +272,29 @@ public IReactiveUIBuilder ForPlatforms(params Action[] platf return this; } + /// + /// Configures the ReactiveUI message bus. + /// + /// The builder instance for chaining. + public IReactiveUIBuilder WithMessageBus() => + WithRegistrationOnBuild(resolver => + { + _messageBus = new MessageBus(); + resolver.RegisterConstant(_messageBus); + }); + /// /// Configures the ReactiveUI message bus. /// /// The configuration action. /// The builder instance for chaining. - public IReactiveUIBuilder ConfigureMessageBus(Action configure) => + public IReactiveUIBuilder WithMessageBus(Action configure) => WithRegistrationOnBuild(resolver => - resolver.Register(() => - { - var messageBus = new MessageBus(); - configure(messageBus); - return messageBus; - })); + { + _messageBus = new MessageBus(); + configure(_messageBus); + resolver.RegisterConstant(_messageBus); + }); /// /// Registers a custom message bus instance. @@ -632,6 +642,18 @@ public IReactiveUIBuilder RegisterViewModel() where TViewModel : class, IReactiveObject, new() => WithRegistration(static resolver => resolver.Register(static () => new())); + /// + /// Registers a constant instance of the specified view model type in the dependency resolver. + /// + /// This method creates a single instance of the specified view model type and registers it as a + /// constant in the resolver. All requests for this view model type will return the same instance. + /// The type of the view model to register. Must be a class that implements IReactiveObject and has a parameterless + /// constructor. + /// The current builder instance, enabling further configuration of the dependency resolver. + public IReactiveUIBuilder RegisterConstantViewModel() + where TViewModel : class, IReactiveObject, new() => + WithRegistration(static resolver => resolver.RegisterConstant(new TViewModel())); + /// /// Registers a custom view model with the dependency resolver. /// diff --git a/src/ReactiveUI/Mixins/BuilderMixins.cs b/src/ReactiveUI/Mixins/BuilderMixins.cs index 3a38bd3135..c1113034a4 100644 --- a/src/ReactiveUI/Mixins/BuilderMixins.cs +++ b/src/ReactiveUI/Mixins/BuilderMixins.cs @@ -306,6 +306,22 @@ public static IReactiveUIBuilder ForPlatforms(this IReactiveUIBuilder reactiveUI return reactiveUIBuilder; } + /// + /// Configures the ReactiveUI message bus. + /// + /// The reactive UI builder. + /// + /// The builder instance for chaining. + /// + /// reactiveUIBuilder. + public static IReactiveUIBuilder WithMessageBus(this IReactiveUIBuilder reactiveUIBuilder) + { + ArgumentExceptionHelper.ThrowIfNull(reactiveUIBuilder); + + reactiveUIBuilder.WithMessageBus(); + return reactiveUIBuilder; + } + /// /// Configures the ReactiveUI message bus. /// @@ -315,11 +331,11 @@ public static IReactiveUIBuilder ForPlatforms(this IReactiveUIBuilder reactiveUI /// The builder instance for chaining. /// /// reactiveUIBuilder. - public static IReactiveUIBuilder ConfigureMessageBus(this IReactiveUIBuilder reactiveUIBuilder, Action configure) + public static IReactiveUIBuilder WithMessageBus(this IReactiveUIBuilder reactiveUIBuilder, Action configure) { ArgumentExceptionHelper.ThrowIfNull(reactiveUIBuilder); - reactiveUIBuilder.ConfigureMessageBus(configure); + reactiveUIBuilder.WithMessageBus(configure); return reactiveUIBuilder; } @@ -392,6 +408,22 @@ public static IReactiveUIBuilder RegisterViewModel(this IReactiveUIB return reactiveUIBuilder; } + /// + /// Registers a constant instance of the specified view model type for use with the ReactiveUI builder. + /// + /// The type of the view model to register. Must be a class that implements IReactiveObject and has a parameterless + /// constructor. + /// The ReactiveUI builder to configure. Cannot be null. + /// The same ReactiveUI builder instance, to allow for method chaining. + public static IReactiveUIBuilder RegisterConstantViewModel(this IReactiveUIBuilder reactiveUIBuilder) + where TViewModel : class, IReactiveObject, new() + { + ArgumentExceptionHelper.ThrowIfNull(reactiveUIBuilder); + + reactiveUIBuilder.RegisterConstantViewModel(); + return reactiveUIBuilder; + } + /// /// Registers a custom view model with the dependency resolver. /// diff --git a/src/examples/ReactiveUI.Builder.BlazorServer/Program.cs b/src/examples/ReactiveUI.Builder.BlazorServer/Program.cs index 4d22fce0c5..13b903a00c 100644 --- a/src/examples/ReactiveUI.Builder.BlazorServer/Program.cs +++ b/src/examples/ReactiveUI.Builder.BlazorServer/Program.cs @@ -8,8 +8,6 @@ using ReactiveUI.Builder.BlazorServer.Components; using ReactiveUI.Builder.BlazorServer.Services; using ReactiveUI.Builder.BlazorServer.ViewModels; -using ReactiveUI.Builder.BlazorServer.Views; -using Splat; using Splat.Microsoft.Extensions.DependencyInjection; var builder = WebApplication.CreateBuilder(args); @@ -30,14 +28,8 @@ RxAppBuilder.CreateReactiveUIBuilder() .WithBlazor() + .WithMessageBus() .WithViewsFromAssembly(typeof(Program).Assembly) - .WithRegistration(locator => - { - if (Locator.Current.GetService() is null) - { - locator.RegisterConstant(MessageBus.Current); - } - }) .BuildApp(); var app = builder.Build(); diff --git a/src/examples/ReactiveUI.Builder.BlazorServer/ReactiveUI.Builder.BlazorServer.csproj b/src/examples/ReactiveUI.Builder.BlazorServer/ReactiveUI.Builder.BlazorServer.csproj index ba1f0c80ad..4396b7a43b 100644 --- a/src/examples/ReactiveUI.Builder.BlazorServer/ReactiveUI.Builder.BlazorServer.csproj +++ b/src/examples/ReactiveUI.Builder.BlazorServer/ReactiveUI.Builder.BlazorServer.csproj @@ -4,6 +4,7 @@ net10.0 enable enable + false true Blazor Server example app for ReactiveUI Builder. diff --git a/src/examples/ReactiveUI.Builder.BlazorServer/Services/FileJsonSuspensionDriver.cs b/src/examples/ReactiveUI.Builder.BlazorServer/Services/FileJsonSuspensionDriver.cs index 41c69399f2..9dd1112f77 100644 --- a/src/examples/ReactiveUI.Builder.BlazorServer/Services/FileJsonSuspensionDriver.cs +++ b/src/examples/ReactiveUI.Builder.BlazorServer/Services/FileJsonSuspensionDriver.cs @@ -3,7 +3,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.IO; using System.Reactive; using System.Reactive.Linq; using System.Text.Json; @@ -70,7 +69,7 @@ public IObservable InvalidateState() => Observable.Start( { if (!File.Exists(path)) { - return default(T); + return default; } var json = File.ReadAllText(path); diff --git a/src/examples/ReactiveUI.Builder.BlazorServer/Services/ReactiveUiAppHostedService.cs b/src/examples/ReactiveUI.Builder.BlazorServer/Services/ReactiveUiAppHostedService.cs index 2312cf22c3..417d9d48e6 100644 --- a/src/examples/ReactiveUI.Builder.BlazorServer/Services/ReactiveUiAppHostedService.cs +++ b/src/examples/ReactiveUI.Builder.BlazorServer/Services/ReactiveUiAppHostedService.cs @@ -5,8 +5,6 @@ using System.Diagnostics; using System.Reactive.Linq; -using Microsoft.Extensions.Hosting; -using ReactiveUI; using ReactiveUI.Builder.BlazorServer.Models; using Splat; diff --git a/src/examples/ReactiveUI.Builder.BlazorServer/Views/LobbyView.razor.cs b/src/examples/ReactiveUI.Builder.BlazorServer/Views/LobbyView.razor.cs index 601db78183..48ff0058a7 100644 --- a/src/examples/ReactiveUI.Builder.BlazorServer/Views/LobbyView.razor.cs +++ b/src/examples/ReactiveUI.Builder.BlazorServer/Views/LobbyView.razor.cs @@ -5,7 +5,6 @@ using System.Reactive.Linq; using Microsoft.AspNetCore.Components.Web; -using ReactiveUI; using ReactiveUI.Blazor; using ReactiveUI.Builder.BlazorServer.Models; using ReactiveUI.Builder.BlazorServer.ViewModels; diff --git a/src/examples/ReactiveUI.Builder.WpfApp/App.xaml.cs b/src/examples/ReactiveUI.Builder.WpfApp/App.xaml.cs index 1bb3998849..1437956d78 100644 --- a/src/examples/ReactiveUI.Builder.WpfApp/App.xaml.cs +++ b/src/examples/ReactiveUI.Builder.WpfApp/App.xaml.cs @@ -35,7 +35,7 @@ protected override void OnStartup(StartupEventArgs e) base.OnStartup(e); // Initialize ReactiveUI via the Builder only - RxAppBuilder.CreateReactiveUIBuilder() + var app = RxAppBuilder.CreateReactiveUIBuilder() .WithWpf() .WithViewsFromAssembly(typeof(App).Assembly) // auto-register all IViewFor in this assembly ////.RegisterView() @@ -52,17 +52,12 @@ protected override void OnStartup(StartupEventArgs e) Debugger.Break(); } })) + .WithMessageBus() .WithRegistration(static r => { // Register IScreen as a singleton so all resolutions share the same Router r.RegisterLazySingleton(static () => new ViewModels.AppBootstrapper()); - // Register MessageBus as a singleton if not already - if (Locator.Current.GetService() is null) - { - r.RegisterConstant(MessageBus.Current); - } - // Cross-process instance lifetime coordination r.RegisterLazySingleton(static () => new Services.AppLifetimeCoordinator()); diff --git a/src/examples/ReactiveUI.Builder.WpfApp/Models/RoomEventMessage.cs b/src/examples/ReactiveUI.Builder.WpfApp/Models/RoomEventMessage.cs index eb32360736..ba4080e590 100644 --- a/src/examples/ReactiveUI.Builder.WpfApp/Models/RoomEventMessage.cs +++ b/src/examples/ReactiveUI.Builder.WpfApp/Models/RoomEventMessage.cs @@ -3,7 +3,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -namespace ReactiveUI.Builder.WpfApp.Services; +using ReactiveUI.Builder.WpfApp.Services; + +namespace ReactiveUI.Builder.WpfApp.Models; /// /// Network event describing a change in the rooms list. diff --git a/src/examples/ReactiveUI.Builder.WpfApp/ReactiveUI.Builder.WpfApp.csproj b/src/examples/ReactiveUI.Builder.WpfApp/ReactiveUI.Builder.WpfApp.csproj index 173a47585f..52e24c8998 100644 --- a/src/examples/ReactiveUI.Builder.WpfApp/ReactiveUI.Builder.WpfApp.csproj +++ b/src/examples/ReactiveUI.Builder.WpfApp/ReactiveUI.Builder.WpfApp.csproj @@ -19,6 +19,14 @@ + + + + + + + + diff --git a/src/tests/ReactiveUI.Blazor.Tests/BlazorReactiveUIBuilderExtensionsTests.cs b/src/tests/ReactiveUI.Blazor.Tests/BlazorReactiveUIBuilderExtensionsTests.cs index c5b60ae4de..62eff81c97 100644 --- a/src/tests/ReactiveUI.Blazor.Tests/BlazorReactiveUIBuilderExtensionsTests.cs +++ b/src/tests/ReactiveUI.Blazor.Tests/BlazorReactiveUIBuilderExtensionsTests.cs @@ -136,8 +136,12 @@ private class TestReactiveUIBuilder : IReactiveUIBuilder { public IScheduler? MainThreadScheduler { get; private set; } + public IScheduler? TaskpoolScheduler { get; private set; } + public bool MainThreadSchedulerSet { get; private set; } + public bool TaskpoolSchedulerSet { get; private set; } + public bool PlatformModuleCalled { get; private set; } public IReactiveUIBuilder WithMainThreadScheduler(IScheduler scheduler, bool setRxApp = true) @@ -165,7 +169,9 @@ public Splat.Builder.IAppBuilder UsingModule(T registrationModule) public Splat.Builder.IAppBuilder WithCustomRegistration(Action configureAction) => throw new NotImplementedException(); - public IReactiveUIBuilder ConfigureMessageBus(Action configure) => throw new NotImplementedException(); + public IReactiveUIBuilder WithMessageBus() => throw new NotImplementedException(); + + public IReactiveUIBuilder WithMessageBus(Action configure) => throw new NotImplementedException(); public IReactiveUIBuilder WithMessageBus(IMessageBus messageBus) => throw new NotImplementedException(); @@ -191,13 +197,21 @@ public IReactiveUIBuilder RegisterView() public IReactiveUIBuilder RegisterViewModel() where TViewModel : class, IReactiveObject, new() => throw new NotImplementedException(); + public IReactiveUIBuilder RegisterConstantViewModel() + where TViewModel : class, IReactiveObject, new() => throw new NotImplementedException(); + public IReactiveUIBuilder WithPlatformServices() => throw new NotImplementedException(); public IReactiveUIBuilder WithRegistration(Action configureAction) => throw new NotImplementedException(); public IReactiveUIBuilder WithRegistrationOnBuild(Action configureAction) => throw new NotImplementedException(); - public IReactiveUIBuilder WithTaskPoolScheduler(IScheduler scheduler, bool setRxApp = true) => throw new NotImplementedException(); + public IReactiveUIBuilder WithTaskPoolScheduler(IScheduler scheduler, bool setRxApp = true) + { + TaskpoolScheduler = scheduler; + TaskpoolSchedulerSet = true; + return this; + } public IReactiveUIBuilder WithViewsFromAssembly(System.Reflection.Assembly assembly) => throw new NotImplementedException(); diff --git a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderMixinsTests.cs b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderMixinsTests.cs index d233f73d38..b410776f5d 100644 --- a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderMixinsTests.cs +++ b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderMixinsTests.cs @@ -31,7 +31,7 @@ static BuilderMixinsTests() () => BuilderMixins.UsingSplatBuilder(null!, _ => { }), () => BuilderMixins.ForCustomPlatform(null!, scheduler, _ => { }), () => BuilderMixins.ForPlatforms(null!, _ => { }), - () => BuilderMixins.ConfigureMessageBus(null!, _ => { }), + () => BuilderMixins.WithMessageBus(null!, _ => { }), () => BuilderMixins.ConfigureViewLocator(null!, _ => { }), () => BuilderMixins.ConfigureSuspensionDriver(null!, _ => { }), () => BuilderMixins.RegisterViewModel(null!), @@ -230,7 +230,7 @@ public async Task ConfigureMessageBus_registers_configured_instance() var builder = resolver.CreateReactiveUIBuilder(); var configured = false; - BuilderMixins.ConfigureMessageBus(builder, _ => configured = true); + BuilderMixins.WithMessageBus(builder, _ => configured = true); builder.WithCoreServices().Build(); using (Assert.Multiple()) diff --git a/src/tests/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet10_0.verified.txt b/src/tests/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet10_0.verified.txt index 049acee93b..62c0950cd3 100644 --- a/src/tests/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet10_0.verified.txt +++ b/src/tests/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet10_0.verified.txt @@ -1957,11 +1957,12 @@ namespace ReactiveUI.Builder public static class BuilderMixins { public static ReactiveUI.Builder.IReactiveUIBuilder BuildApp(this Splat.Builder.IAppBuilder appBuilder) { } - public static ReactiveUI.Builder.IReactiveUIBuilder ConfigureMessageBus(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Action configure) { } public static ReactiveUI.Builder.IReactiveUIBuilder ConfigureSuspensionDriver(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Action configure) { } public static ReactiveUI.Builder.IReactiveUIBuilder ConfigureViewLocator(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Action configure) { } public static ReactiveUI.Builder.IReactiveUIBuilder ForCustomPlatform(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Reactive.Concurrency.IScheduler mainThreadScheduler, System.Action platformServices) { } public static ReactiveUI.Builder.IReactiveUIBuilder ForPlatforms(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, params System.Action[] platformConfigurations) { } + public static ReactiveUI.Builder.IReactiveUIBuilder RegisterConstantViewModel(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder) + where TViewModel : class, ReactiveUI.IReactiveObject, new () { } public static ReactiveUI.Builder.IReactiveUIBuilder RegisterSingletonView(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder) where TView : class, ReactiveUI.IViewFor, new () where TViewModel : class, ReactiveUI.IReactiveObject { } @@ -2001,7 +2002,9 @@ namespace ReactiveUI.Builder public static ReactiveUI.Builder.IReactiveUIInstance WithInstance(this ReactiveUI.Builder.IReactiveUIInstance reactiveUIInstance, System.Action action) { } public static ReactiveUI.Builder.IReactiveUIInstance WithInstance(this ReactiveUI.Builder.IReactiveUIInstance reactiveUIInstance, System.Action action) { } public static ReactiveUI.Builder.IReactiveUIBuilder WithMainThreadScheduler(this ReactiveUI.Builder.IReactiveUIBuilder builder, System.Reactive.Concurrency.IScheduler scheduler, bool setRxApp = true) { } + public static ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder) { } public static ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, ReactiveUI.IMessageBus messageBus) { } + public static ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Action configure) { } public static ReactiveUI.Builder.IReactiveUIBuilder WithPlatformModule(this ReactiveUI.Builder.IReactiveUIBuilder builder) where T : ReactiveUI.IWantsToRegisterStuff, new () { } public static ReactiveUI.Builder.IReactiveUIBuilder WithRegistration(this ReactiveUI.Builder.IReactiveUIBuilder builder, System.Action configureAction) { } @@ -2018,11 +2021,12 @@ namespace ReactiveUI.Builder public interface IReactiveUIBuilder : Splat.Builder.IAppBuilder { ReactiveUI.Builder.IReactiveUIInstance BuildApp(); - ReactiveUI.Builder.IReactiveUIBuilder ConfigureMessageBus(System.Action configure); ReactiveUI.Builder.IReactiveUIBuilder ConfigureSuspensionDriver(System.Action configure); ReactiveUI.Builder.IReactiveUIBuilder ConfigureViewLocator(System.Action configure); ReactiveUI.Builder.IReactiveUIBuilder ForCustomPlatform(System.Reactive.Concurrency.IScheduler mainThreadScheduler, System.Action platformServices); ReactiveUI.Builder.IReactiveUIBuilder ForPlatforms(params System.Action[] platformConfigurations); + ReactiveUI.Builder.IReactiveUIBuilder RegisterConstantViewModel() + where TViewModel : class, ReactiveUI.IReactiveObject, new (); ReactiveUI.Builder.IReactiveUIBuilder RegisterSingletonView() where TView : class, ReactiveUI.IViewFor, new () where TViewModel : class, ReactiveUI.IReactiveObject; @@ -2054,7 +2058,9 @@ namespace ReactiveUI.Builder ReactiveUI.Builder.IReactiveUIInstance WithInstance(System.Action action); ReactiveUI.Builder.IReactiveUIInstance WithInstance(System.Action action); ReactiveUI.Builder.IReactiveUIBuilder WithMainThreadScheduler(System.Reactive.Concurrency.IScheduler scheduler, bool setRxApp = true); + ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(); ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(ReactiveUI.IMessageBus messageBus); + ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(System.Action configure); ReactiveUI.Builder.IReactiveUIBuilder WithPlatformModule() where T : ReactiveUI.IWantsToRegisterStuff, new (); ReactiveUI.Builder.IReactiveUIBuilder WithPlatformServices(); @@ -2079,11 +2085,12 @@ namespace ReactiveUI.Builder public System.Reactive.Concurrency.IScheduler? MainThreadScheduler { get; } public System.Reactive.Concurrency.IScheduler? TaskpoolScheduler { get; } public ReactiveUI.Builder.IReactiveUIInstance BuildApp() { } - public ReactiveUI.Builder.IReactiveUIBuilder ConfigureMessageBus(System.Action configure) { } public ReactiveUI.Builder.IReactiveUIBuilder ConfigureSuspensionDriver(System.Action configure) { } public ReactiveUI.Builder.IReactiveUIBuilder ConfigureViewLocator(System.Action configure) { } public ReactiveUI.Builder.IReactiveUIBuilder ForCustomPlatform(System.Reactive.Concurrency.IScheduler mainThreadScheduler, System.Action platformServices) { } public ReactiveUI.Builder.IReactiveUIBuilder ForPlatforms(params System.Action[] platformConfigurations) { } + public ReactiveUI.Builder.IReactiveUIBuilder RegisterConstantViewModel() + where TViewModel : class, ReactiveUI.IReactiveObject, new () { } public ReactiveUI.Builder.IReactiveUIBuilder RegisterSingletonView() where TView : class, ReactiveUI.IViewFor, new () where TViewModel : class, ReactiveUI.IReactiveObject { } @@ -2124,7 +2131,9 @@ namespace ReactiveUI.Builder public ReactiveUI.Builder.IReactiveUIInstance WithInstance(System.Action action) { } public ReactiveUI.Builder.IReactiveUIInstance WithInstance(System.Action action) { } public ReactiveUI.Builder.IReactiveUIBuilder WithMainThreadScheduler(System.Reactive.Concurrency.IScheduler scheduler, bool setRxApp = true) { } + public ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus() { } public ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(ReactiveUI.IMessageBus messageBus) { } + public ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(System.Action configure) { } public ReactiveUI.Builder.IReactiveUIBuilder WithPlatformModule() where T : ReactiveUI.IWantsToRegisterStuff, new () { } public ReactiveUI.Builder.IReactiveUIBuilder WithPlatformServices() { } diff --git a/src/tests/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet8_0.verified.txt b/src/tests/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet8_0.verified.txt index 049acee93b..62c0950cd3 100644 --- a/src/tests/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet8_0.verified.txt +++ b/src/tests/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet8_0.verified.txt @@ -1957,11 +1957,12 @@ namespace ReactiveUI.Builder public static class BuilderMixins { public static ReactiveUI.Builder.IReactiveUIBuilder BuildApp(this Splat.Builder.IAppBuilder appBuilder) { } - public static ReactiveUI.Builder.IReactiveUIBuilder ConfigureMessageBus(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Action configure) { } public static ReactiveUI.Builder.IReactiveUIBuilder ConfigureSuspensionDriver(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Action configure) { } public static ReactiveUI.Builder.IReactiveUIBuilder ConfigureViewLocator(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Action configure) { } public static ReactiveUI.Builder.IReactiveUIBuilder ForCustomPlatform(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Reactive.Concurrency.IScheduler mainThreadScheduler, System.Action platformServices) { } public static ReactiveUI.Builder.IReactiveUIBuilder ForPlatforms(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, params System.Action[] platformConfigurations) { } + public static ReactiveUI.Builder.IReactiveUIBuilder RegisterConstantViewModel(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder) + where TViewModel : class, ReactiveUI.IReactiveObject, new () { } public static ReactiveUI.Builder.IReactiveUIBuilder RegisterSingletonView(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder) where TView : class, ReactiveUI.IViewFor, new () where TViewModel : class, ReactiveUI.IReactiveObject { } @@ -2001,7 +2002,9 @@ namespace ReactiveUI.Builder public static ReactiveUI.Builder.IReactiveUIInstance WithInstance(this ReactiveUI.Builder.IReactiveUIInstance reactiveUIInstance, System.Action action) { } public static ReactiveUI.Builder.IReactiveUIInstance WithInstance(this ReactiveUI.Builder.IReactiveUIInstance reactiveUIInstance, System.Action action) { } public static ReactiveUI.Builder.IReactiveUIBuilder WithMainThreadScheduler(this ReactiveUI.Builder.IReactiveUIBuilder builder, System.Reactive.Concurrency.IScheduler scheduler, bool setRxApp = true) { } + public static ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder) { } public static ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, ReactiveUI.IMessageBus messageBus) { } + public static ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Action configure) { } public static ReactiveUI.Builder.IReactiveUIBuilder WithPlatformModule(this ReactiveUI.Builder.IReactiveUIBuilder builder) where T : ReactiveUI.IWantsToRegisterStuff, new () { } public static ReactiveUI.Builder.IReactiveUIBuilder WithRegistration(this ReactiveUI.Builder.IReactiveUIBuilder builder, System.Action configureAction) { } @@ -2018,11 +2021,12 @@ namespace ReactiveUI.Builder public interface IReactiveUIBuilder : Splat.Builder.IAppBuilder { ReactiveUI.Builder.IReactiveUIInstance BuildApp(); - ReactiveUI.Builder.IReactiveUIBuilder ConfigureMessageBus(System.Action configure); ReactiveUI.Builder.IReactiveUIBuilder ConfigureSuspensionDriver(System.Action configure); ReactiveUI.Builder.IReactiveUIBuilder ConfigureViewLocator(System.Action configure); ReactiveUI.Builder.IReactiveUIBuilder ForCustomPlatform(System.Reactive.Concurrency.IScheduler mainThreadScheduler, System.Action platformServices); ReactiveUI.Builder.IReactiveUIBuilder ForPlatforms(params System.Action[] platformConfigurations); + ReactiveUI.Builder.IReactiveUIBuilder RegisterConstantViewModel() + where TViewModel : class, ReactiveUI.IReactiveObject, new (); ReactiveUI.Builder.IReactiveUIBuilder RegisterSingletonView() where TView : class, ReactiveUI.IViewFor, new () where TViewModel : class, ReactiveUI.IReactiveObject; @@ -2054,7 +2058,9 @@ namespace ReactiveUI.Builder ReactiveUI.Builder.IReactiveUIInstance WithInstance(System.Action action); ReactiveUI.Builder.IReactiveUIInstance WithInstance(System.Action action); ReactiveUI.Builder.IReactiveUIBuilder WithMainThreadScheduler(System.Reactive.Concurrency.IScheduler scheduler, bool setRxApp = true); + ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(); ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(ReactiveUI.IMessageBus messageBus); + ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(System.Action configure); ReactiveUI.Builder.IReactiveUIBuilder WithPlatformModule() where T : ReactiveUI.IWantsToRegisterStuff, new (); ReactiveUI.Builder.IReactiveUIBuilder WithPlatformServices(); @@ -2079,11 +2085,12 @@ namespace ReactiveUI.Builder public System.Reactive.Concurrency.IScheduler? MainThreadScheduler { get; } public System.Reactive.Concurrency.IScheduler? TaskpoolScheduler { get; } public ReactiveUI.Builder.IReactiveUIInstance BuildApp() { } - public ReactiveUI.Builder.IReactiveUIBuilder ConfigureMessageBus(System.Action configure) { } public ReactiveUI.Builder.IReactiveUIBuilder ConfigureSuspensionDriver(System.Action configure) { } public ReactiveUI.Builder.IReactiveUIBuilder ConfigureViewLocator(System.Action configure) { } public ReactiveUI.Builder.IReactiveUIBuilder ForCustomPlatform(System.Reactive.Concurrency.IScheduler mainThreadScheduler, System.Action platformServices) { } public ReactiveUI.Builder.IReactiveUIBuilder ForPlatforms(params System.Action[] platformConfigurations) { } + public ReactiveUI.Builder.IReactiveUIBuilder RegisterConstantViewModel() + where TViewModel : class, ReactiveUI.IReactiveObject, new () { } public ReactiveUI.Builder.IReactiveUIBuilder RegisterSingletonView() where TView : class, ReactiveUI.IViewFor, new () where TViewModel : class, ReactiveUI.IReactiveObject { } @@ -2124,7 +2131,9 @@ namespace ReactiveUI.Builder public ReactiveUI.Builder.IReactiveUIInstance WithInstance(System.Action action) { } public ReactiveUI.Builder.IReactiveUIInstance WithInstance(System.Action action) { } public ReactiveUI.Builder.IReactiveUIBuilder WithMainThreadScheduler(System.Reactive.Concurrency.IScheduler scheduler, bool setRxApp = true) { } + public ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus() { } public ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(ReactiveUI.IMessageBus messageBus) { } + public ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(System.Action configure) { } public ReactiveUI.Builder.IReactiveUIBuilder WithPlatformModule() where T : ReactiveUI.IWantsToRegisterStuff, new () { } public ReactiveUI.Builder.IReactiveUIBuilder WithPlatformServices() { } diff --git a/src/tests/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet9_0.verified.txt b/src/tests/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet9_0.verified.txt index 049acee93b..62c0950cd3 100644 --- a/src/tests/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet9_0.verified.txt +++ b/src/tests/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet9_0.verified.txt @@ -1957,11 +1957,12 @@ namespace ReactiveUI.Builder public static class BuilderMixins { public static ReactiveUI.Builder.IReactiveUIBuilder BuildApp(this Splat.Builder.IAppBuilder appBuilder) { } - public static ReactiveUI.Builder.IReactiveUIBuilder ConfigureMessageBus(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Action configure) { } public static ReactiveUI.Builder.IReactiveUIBuilder ConfigureSuspensionDriver(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Action configure) { } public static ReactiveUI.Builder.IReactiveUIBuilder ConfigureViewLocator(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Action configure) { } public static ReactiveUI.Builder.IReactiveUIBuilder ForCustomPlatform(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Reactive.Concurrency.IScheduler mainThreadScheduler, System.Action platformServices) { } public static ReactiveUI.Builder.IReactiveUIBuilder ForPlatforms(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, params System.Action[] platformConfigurations) { } + public static ReactiveUI.Builder.IReactiveUIBuilder RegisterConstantViewModel(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder) + where TViewModel : class, ReactiveUI.IReactiveObject, new () { } public static ReactiveUI.Builder.IReactiveUIBuilder RegisterSingletonView(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder) where TView : class, ReactiveUI.IViewFor, new () where TViewModel : class, ReactiveUI.IReactiveObject { } @@ -2001,7 +2002,9 @@ namespace ReactiveUI.Builder public static ReactiveUI.Builder.IReactiveUIInstance WithInstance(this ReactiveUI.Builder.IReactiveUIInstance reactiveUIInstance, System.Action action) { } public static ReactiveUI.Builder.IReactiveUIInstance WithInstance(this ReactiveUI.Builder.IReactiveUIInstance reactiveUIInstance, System.Action action) { } public static ReactiveUI.Builder.IReactiveUIBuilder WithMainThreadScheduler(this ReactiveUI.Builder.IReactiveUIBuilder builder, System.Reactive.Concurrency.IScheduler scheduler, bool setRxApp = true) { } + public static ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder) { } public static ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, ReactiveUI.IMessageBus messageBus) { } + public static ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(this ReactiveUI.Builder.IReactiveUIBuilder reactiveUIBuilder, System.Action configure) { } public static ReactiveUI.Builder.IReactiveUIBuilder WithPlatformModule(this ReactiveUI.Builder.IReactiveUIBuilder builder) where T : ReactiveUI.IWantsToRegisterStuff, new () { } public static ReactiveUI.Builder.IReactiveUIBuilder WithRegistration(this ReactiveUI.Builder.IReactiveUIBuilder builder, System.Action configureAction) { } @@ -2018,11 +2021,12 @@ namespace ReactiveUI.Builder public interface IReactiveUIBuilder : Splat.Builder.IAppBuilder { ReactiveUI.Builder.IReactiveUIInstance BuildApp(); - ReactiveUI.Builder.IReactiveUIBuilder ConfigureMessageBus(System.Action configure); ReactiveUI.Builder.IReactiveUIBuilder ConfigureSuspensionDriver(System.Action configure); ReactiveUI.Builder.IReactiveUIBuilder ConfigureViewLocator(System.Action configure); ReactiveUI.Builder.IReactiveUIBuilder ForCustomPlatform(System.Reactive.Concurrency.IScheduler mainThreadScheduler, System.Action platformServices); ReactiveUI.Builder.IReactiveUIBuilder ForPlatforms(params System.Action[] platformConfigurations); + ReactiveUI.Builder.IReactiveUIBuilder RegisterConstantViewModel() + where TViewModel : class, ReactiveUI.IReactiveObject, new (); ReactiveUI.Builder.IReactiveUIBuilder RegisterSingletonView() where TView : class, ReactiveUI.IViewFor, new () where TViewModel : class, ReactiveUI.IReactiveObject; @@ -2054,7 +2058,9 @@ namespace ReactiveUI.Builder ReactiveUI.Builder.IReactiveUIInstance WithInstance(System.Action action); ReactiveUI.Builder.IReactiveUIInstance WithInstance(System.Action action); ReactiveUI.Builder.IReactiveUIBuilder WithMainThreadScheduler(System.Reactive.Concurrency.IScheduler scheduler, bool setRxApp = true); + ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(); ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(ReactiveUI.IMessageBus messageBus); + ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(System.Action configure); ReactiveUI.Builder.IReactiveUIBuilder WithPlatformModule() where T : ReactiveUI.IWantsToRegisterStuff, new (); ReactiveUI.Builder.IReactiveUIBuilder WithPlatformServices(); @@ -2079,11 +2085,12 @@ namespace ReactiveUI.Builder public System.Reactive.Concurrency.IScheduler? MainThreadScheduler { get; } public System.Reactive.Concurrency.IScheduler? TaskpoolScheduler { get; } public ReactiveUI.Builder.IReactiveUIInstance BuildApp() { } - public ReactiveUI.Builder.IReactiveUIBuilder ConfigureMessageBus(System.Action configure) { } public ReactiveUI.Builder.IReactiveUIBuilder ConfigureSuspensionDriver(System.Action configure) { } public ReactiveUI.Builder.IReactiveUIBuilder ConfigureViewLocator(System.Action configure) { } public ReactiveUI.Builder.IReactiveUIBuilder ForCustomPlatform(System.Reactive.Concurrency.IScheduler mainThreadScheduler, System.Action platformServices) { } public ReactiveUI.Builder.IReactiveUIBuilder ForPlatforms(params System.Action[] platformConfigurations) { } + public ReactiveUI.Builder.IReactiveUIBuilder RegisterConstantViewModel() + where TViewModel : class, ReactiveUI.IReactiveObject, new () { } public ReactiveUI.Builder.IReactiveUIBuilder RegisterSingletonView() where TView : class, ReactiveUI.IViewFor, new () where TViewModel : class, ReactiveUI.IReactiveObject { } @@ -2124,7 +2131,9 @@ namespace ReactiveUI.Builder public ReactiveUI.Builder.IReactiveUIInstance WithInstance(System.Action action) { } public ReactiveUI.Builder.IReactiveUIInstance WithInstance(System.Action action) { } public ReactiveUI.Builder.IReactiveUIBuilder WithMainThreadScheduler(System.Reactive.Concurrency.IScheduler scheduler, bool setRxApp = true) { } + public ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus() { } public ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(ReactiveUI.IMessageBus messageBus) { } + public ReactiveUI.Builder.IReactiveUIBuilder WithMessageBus(System.Action configure) { } public ReactiveUI.Builder.IReactiveUIBuilder WithPlatformModule() where T : ReactiveUI.IWantsToRegisterStuff, new () { } public ReactiveUI.Builder.IReactiveUIBuilder WithPlatformServices() { } From 694367915ff8cb68fd3ad0ad761b4bfa8cc03af1 Mon Sep 17 00:00:00 2001 From: Chris Pulman Date: Sat, 31 Jan 2026 22:45:17 +0000 Subject: [PATCH 2/2] Replace fully-qualified RoomEventMessage refs Replace occurrences of Services.RoomEventMessage with the unqualified RoomEventMessage in LobbyViewModel. Updates message listening, sync request/response creation, ApplyRoomEvent signature, and broadcast events for room create/delete to use the shorter type name. --- .../ViewModels/LobbyViewModel.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/examples/ReactiveUI.Builder.WpfApp/ViewModels/LobbyViewModel.cs b/src/examples/ReactiveUI.Builder.WpfApp/ViewModels/LobbyViewModel.cs index 1c5b7e9e78..5a6943dd1d 100644 --- a/src/examples/ReactiveUI.Builder.WpfApp/ViewModels/LobbyViewModel.cs +++ b/src/examples/ReactiveUI.Builder.WpfApp/ViewModels/LobbyViewModel.cs @@ -46,7 +46,7 @@ public LobbyViewModel(IScreen hostScreen) // Remote changes and sync (ignore own events) var remoteRoomsChanged = MessageBus.Current - .Listen(contract: "__rooms__") + .Listen(contract: "__rooms__") .Where(m => m.InstanceId != Services.AppInstance.Id) .Do(evt => { @@ -56,7 +56,7 @@ public LobbyViewModel(IScreen hostScreen) case Services.RoomEventKind.SyncRequest: // Respond with our snapshot of room names var snapshot = GetState().Rooms.ConvertAll(r => r.Name); - var response = new Services.RoomEventMessage(Services.RoomEventKind.Add, string.Empty) + var response = new RoomEventMessage(Services.RoomEventKind.Add, string.Empty) { Snapshot = snapshot, InstanceId = Services.AppInstance.Id, @@ -82,7 +82,7 @@ public LobbyViewModel(IScreen hostScreen) // Request a snapshot from peers shortly after activation RxSchedulers.MainThreadScheduler.Schedule(Unit.Default, TimeSpan.FromMilliseconds(500), (s, __) => { - var req = new Services.RoomEventMessage(Services.RoomEventKind.SyncRequest, string.Empty) { InstanceId = Services.AppInstance.Id }; + var req = new RoomEventMessage(Services.RoomEventKind.SyncRequest, string.Empty) { InstanceId = Services.AppInstance.Id }; Trace.WriteLine("[Lobby] Broadcasting SyncRequest"); MessageBus.Current.SendMessage(req, contract: "__rooms__"); return Disposable.Empty; @@ -140,7 +140,7 @@ public string RoomName private static ChatState GetState() => RxSuspension.SuspensionHost.GetAppState(); - private static void ApplyRoomEvent(Services.RoomEventMessage evt) + private static void ApplyRoomEvent(RoomEventMessage evt) { var state = GetState(); @@ -184,7 +184,7 @@ private void CreateRoomImpl() state.Rooms.Add(room); // Broadcast room add to peers - var evt = new Services.RoomEventMessage(Services.RoomEventKind.Add, room.Name) { InstanceId = Services.AppInstance.Id }; + var evt = new RoomEventMessage(Services.RoomEventKind.Add, room.Name) { InstanceId = Services.AppInstance.Id }; MessageBus.Current.SendMessage(evt, contract: "__rooms__"); Trace.WriteLine($"[Lobby] Created room '{room.Name}'"); } @@ -198,7 +198,7 @@ private void DeleteRoomImpl(ChatRoom room) var state = GetState(); if (state.Rooms.Remove(room)) { - var evt = new Services.RoomEventMessage(Services.RoomEventKind.Remove, room.Name) { InstanceId = Services.AppInstance.Id }; + var evt = new RoomEventMessage(Services.RoomEventKind.Remove, room.Name) { InstanceId = Services.AppInstance.Id }; MessageBus.Current.SendMessage(evt, contract: "__rooms__"); MessageBus.Current.SendMessage(new ChatStateChanged()); Trace.WriteLine($"[Lobby] Deleted room '{room.Name}'");