From f0bca16d0ce2323a85f2b3261ba108992549c41f Mon Sep 17 00:00:00 2001 From: Glenn Watson <5834289+glennawatson@users.noreply.github.com> Date: Sat, 3 Oct 2026 14:49:44 +1000 Subject: [PATCH] fix: make view WhenActivated trim and AOT safe - Watch IViewFor.ViewModel through the registered ICreatesObservableForProperty plugin, as the binding generator does, instead of WhenAnyValueUnsafe. - Fall back to the current ViewModel once when no plugin can watch the property. - Remove RequiresUnreferencedCode from the IActivatableView and WPF WhenActivated overloads. - Remove the design-mode branch in view activation. IActivatableView.GetIsDesignMode always returns false there, so it never ran. - Update the WPF public API baselines. - Build the .NET 11 assemblies without runtime-async. Mono does not support it, so it breaks Blazor WebAssembly and other Mono hosts. - Update ReactiveUI.Binding to 9.0.0, TUnit to 1.72.16, SonarAnalyzer.CSharp to 10.35.0.4138 and the Blazor WASM example's Microsoft.AspNetCore.Components to 10.0.12. Co-Authored-By: Claude Opus 5.5 --- src/Directory.Build.props | 3 - src/Directory.Packages.props | 6 +- .../Activation/ViewForMixins.cs | 121 ++++++++---------- .../PublicAPI/net10.0-windows/PublicAPI.txt | 7 - .../net10.0-windows10.0.19041.0/PublicAPI.txt | 7 - .../PublicAPI/net11.0-windows/PublicAPI.txt | 7 - .../net11.0-windows10.0.19041.0/PublicAPI.txt | 7 - .../PublicAPI/net8.0-windows/PublicAPI.txt | 7 - .../net8.0-windows10.0.19041.0/PublicAPI.txt | 7 - .../PublicAPI/net9.0-windows/PublicAPI.txt | 7 - .../net9.0-windows10.0.19041.0/PublicAPI.txt | 7 - src/ReactiveUI.Wpf.Shared/WpfViewForMixins.cs | 8 -- .../PublicAPI/net10.0-windows/PublicAPI.txt | 7 - .../net10.0-windows10.0.19041.0/PublicAPI.txt | 7 - .../PublicAPI/net11.0-windows/PublicAPI.txt | 7 - .../net11.0-windows10.0.19041.0/PublicAPI.txt | 7 - .../PublicAPI/net8.0-windows/PublicAPI.txt | 7 - .../net8.0-windows10.0.19041.0/PublicAPI.txt | 7 - .../PublicAPI/net9.0-windows/PublicAPI.txt | 7 - .../net9.0-windows10.0.19041.0/PublicAPI.txt | 7 - .../ReactiveUI.Builder.BlazorWasm.csproj | 2 +- .../Activation/ActivatingViewTests.cs | 33 +++++ 22 files changed, 92 insertions(+), 193 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 75ac8a0949..321588aeaf 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -160,9 +160,6 @@ true - - $(Features);runtime-async=on - diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index c74fe00fdd..98fd83e2a3 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -7,8 +7,8 @@ 21.0.0 8.4.0 - 8.8.0 - 1.69.16 + 9.0.0 + 1.72.16 5.1.2 @@ -102,7 +102,7 @@ - + diff --git a/src/ReactiveUI.Shared/Activation/ViewForMixins.cs b/src/ReactiveUI.Shared/Activation/ViewForMixins.cs index 880c0c7aae..770530e2ac 100644 --- a/src/ReactiveUI.Shared/Activation/ViewForMixins.cs +++ b/src/ReactiveUI.Shared/Activation/ViewForMixins.cs @@ -13,6 +13,14 @@ using ReactiveUI.Primitives.Disposables; using Splat; +#if REACTIVE_SHIM +using ReactiveUI.Binding.Reactive.Fallback; +using ReactiveUI.Binding.Reactive.Observables; +#else +using ReactiveUI.Binding.Fallback; +using ReactiveUI.Binding.Observables; +#endif + #if REACTIVE_SHIM namespace ReactiveUI.Reactive; #else @@ -50,7 +58,6 @@ public static class ViewForMixins /// A function that returns a collection of objects to be disposed when the view is /// deactivated. Cannot be null. /// An that deactivates the view and disposes the registered disposables when disposed. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public IDisposable WhenActivated(Func> block) { @@ -73,7 +80,6 @@ public IDisposable /// This method is typically used to manage subscriptions or other resources that should only be /// active while the view or view model is active. The activation lifecycle is determined by the implementation of /// and any registered activation fetchers. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public IDisposable WhenActivated( Func> block, IViewFor? view) @@ -81,11 +87,6 @@ public IDisposable WhenActivated( ArgumentExceptionHelper.ThrowIfNull(item); var activationEvents = ResolveActivationEvents(item); - if (activationEvents is null) - { - // No activation fetcher in design mode: no-op rather than throwing (see #4358). - return EmptyDisposable.Instance; - } IDisposable viewModelDisposable = EmptyDisposable.Instance; if ((view ?? item) is IViewFor v) @@ -108,7 +109,6 @@ public IDisposable WhenActivated( /// Use this method to manage resources or subscriptions that should only be active while the /// view is active. The provided block is invoked each time the view is activated, and any disposables registered /// within the block are disposed when the view is deactivated. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [MethodImpl(MethodImplOptions.AggressiveInlining)] public IDisposable WhenActivated(Action> block) => item.WhenActivated(block, (IViewFor)null!); @@ -120,9 +120,7 @@ public IDisposable WhenActivated(Action> block) => /// An that deactivates the view and disposes all registered resources when disposed. /// This method is typically used to manage subscriptions or other resources that should be tied /// to the view's activation lifecycle. All disposables registered via the provided callback will be disposed when - /// the returned is disposed. Reflection is used to evaluate expression-based member - /// chains, which may be affected by trimming in some deployment scenarios. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] + /// the returned is disposed. [MethodImpl(MethodImplOptions.AggressiveInlining)] public IDisposable WhenActivated( Action> block, @@ -142,7 +140,6 @@ public IDisposable WhenActivated( /// /// An action that receives an to which activation-related disposables should be added. /// An IDisposable that deactivates the view and disposes of all registered disposables when disposed. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [MethodImpl(MethodImplOptions.AggressiveInlining)] public IDisposable WhenActivated( Action block) => @@ -155,7 +152,6 @@ public IDisposable WhenActivated( /// An action that receives an to which activation-related disposables should be added. /// An optional IViewFor instance representing the view context. If null, the item itself is used as the view. /// An IDisposable that deactivates the view and disposes of all registered disposables when disposed. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [MethodImpl(MethodImplOptions.AggressiveInlining)] public IDisposable WhenActivated( Action block, @@ -173,7 +169,6 @@ public IDisposable WhenActivated( /// An that deactivates the view and disposes registered resources when disposed. /// Use this no-op overload purely to trigger activation when the /// view itself has no resources to manage — it avoids the empty WhenActivated(_ => { }) boilerplate. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [MethodImpl(MethodImplOptions.AggressiveInlining)] public IDisposable WhenActivated() => item.WhenActivated(static () => (IEnumerable)[], (IViewFor?)null); @@ -188,13 +183,9 @@ public IDisposable WhenActivated() => /// value is an , its activator is activated for the duration of the view's activation. /// An that deactivates the view and disposes the registered resources when disposed. /// - /// This is the trim- and AOT-safe counterpart to the reflected WhenActivated(block, IViewFor) overloads: - /// they discover the view's ViewModel with an expression/string-based WhenAnyValue, which requires - /// unreferenced code. Here the caller passes directly, so no reflection is - /// used and the member carries no [RequiresUnreferencedCode] annotation. Emit the current ViewModel (and - /// every subsequent value, e.g. on clear) on using a - /// reflection-free source such as the source-generated WhenAnyValue from ReactiveUI.SourceGenerators - /// or a hand-written subscription. + /// Use this overload when the view already has a cheaper ViewModel-change signal than the registered + /// plugins. Emit the current ViewModel and every later value, + /// including on clear. /// public IDisposable WhenActivated( Func> block, @@ -204,11 +195,6 @@ public IDisposable WhenActivated( ArgumentExceptionHelper.ThrowIfNull(viewModelChanged); var activationEvents = ResolveActivationEvents(item); - if (activationEvents is null) - { - // No activation fetcher in design mode: no-op rather than throwing (see #4358). - return EmptyDisposable.Instance; - } var viewModelDisposable = HandleViewModelActivation(viewModelChanged, activationEvents); var viewDisposable = HandleViewActivation(block, activationEvents); @@ -222,10 +208,6 @@ public IDisposable WhenActivated( /// An action that receives a callback for registering disposables that should be disposed when the view is deactivated. /// An observable that emits the view's ViewModel whenever it changes (including its current value). /// An that deactivates the view and disposes the registered resources when disposed. - /// This is the trim- and AOT-safe counterpart to the reflected WhenActivated(Action<Action<IDisposable>>, IViewFor) - /// overload; the observable replaces reflection-based ViewModel discovery. Produce it with a - /// reflection-free source such as the source-generated WhenAnyValue or a hand-written - /// subscription. [MethodImpl(MethodImplOptions.AggressiveInlining)] public IDisposable WhenActivated( Action> block, @@ -246,10 +228,6 @@ public IDisposable WhenActivated( /// An action that receives an to which activation-related disposables can be added. /// An observable that emits the view's ViewModel whenever it changes (including its current value). /// An that deactivates the view and disposes the registered resources when disposed. - /// This is the trim- and AOT-safe counterpart to the reflected WhenActivated(Action<ActivationDisposables>, IViewFor) - /// overload; the observable replaces reflection-based ViewModel discovery. Produce it with a - /// reflection-free source such as the source-generated WhenAnyValue or a hand-written - /// subscription. [MethodImpl(MethodImplOptions.AggressiveInlining)] public IDisposable WhenActivated( Action block, @@ -269,10 +247,6 @@ public IDisposable WhenActivated( /// /// An observable that emits the view's ViewModel whenever it changes (including its current value). /// An that deactivates the view and disposes registered resources when disposed. - /// This is the trim- and AOT-safe counterpart to the reflected parameterless WhenActivated() overload; - /// the observable replaces reflection-based ViewModel discovery. Produce it with a - /// reflection-free source such as the source-generated WhenAnyValue or a hand-written - /// subscription. [MethodImpl(MethodImplOptions.AggressiveInlining)] public IDisposable WhenActivated(IObservable viewModelChanged) => item.WhenActivated(static () => (IEnumerable)[], viewModelChanged); @@ -384,32 +358,24 @@ public void /// Resolves the activation event stream for the view via its highest-affinity activation fetcher. /// The view to resolve activation events for. - /// - /// An observable that emits on activation and on deactivation, or - /// when the view is in design mode and has no activation fetcher, signalling a no-op (see #4358). - /// - /// Thrown when no registered can determine activation for the view type and the view is not in design mode. - private static IObservable? ResolveActivationEvents(IActivatableView item) + /// An observable that emits on activation and on deactivation. + /// Thrown when no registered can determine activation for the view type. + private static IObservable ResolveActivationEvents(IActivatableView item) { - var activationFetcher = _activationFetcherCache.Get(item.GetType()); - if (activationFetcher is null) - { - // In design mode there is no activation fetcher; drop the cache and signal a no-op rather than throwing (see #4358). - if (item.GetIsDesignMode()) - { - _activationFetcherCache.InvalidateAll(); - return null; - } + var activationFetcher = _activationFetcherCache.Get(item.GetType()) ?? throw CreateActivationDetectionFailure(item); + + return activationFetcher.GetActivationForView(item); + } + /// Creates the exception reported when no activation fetcher can handle a view type. + /// The view that could not be activated. + /// The exception to throw. + private static ArgumentException CreateActivationDetectionFailure(IActivatableView item) => #if NET8_0_OR_GREATER - throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, _activationDetectionFailureFormat, item.GetType().FullName)); + new(string.Format(CultureInfo.InvariantCulture, _activationDetectionFailureFormat, item.GetType().FullName)); #else - throw new ArgumentException($"Don't know how to detect when {item.GetType().FullName} is activated/deactivated, you may need to implement IActivationForViewFetcher"); + new($"Don't know how to detect when {item.GetType().FullName} is activated/deactivated, you may need to implement IActivationForViewFetcher"); #endif - } - - return activationFetcher.GetActivationForView(item); - } /// /// Manages the activation and deactivation lifecycle of a view by subscribing to an activation observable and @@ -451,17 +417,11 @@ private static MultipleDisposable HandleViewActivation( /// indicate activation and for deactivation. /// A MultipleDisposable that manages all subscriptions and resources related to the activation lifecycle. /// Disposing this object will clean up all associated subscriptions. - /// This bridge discovers the view's ViewModel with an expression/string-based WhenAnyValue — the only - /// reflection in the activation path — and forwards to the reflection-free . - /// Callers that already have a ViewModel-change observable should use that overload to stay trim- and AOT-safe. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [MethodImpl(MethodImplOptions.AggressiveInlining)] private static MultipleDisposable HandleViewModelActivation( IViewFor view, IObservable activation) => - HandleViewModelActivation( - view.WhenAnyValueUnsafe(x => x.ViewModel), - activation); + HandleViewModelActivation(ObserveViewModel(view), activation); /// Manages the activation and deactivation lifecycle of a view's ViewModel in response to an activation observable, without reflection. /// An observable that emits the view's ViewModel whenever it changes (including its current value). @@ -503,4 +463,33 @@ private static MultipleDisposable HandleViewModelActivation(IObservable viewModelDisposable, viewViewModelDisposable); } + + /// Observes the ViewModel of a view without reflection. + /// The view whose ViewModel to observe. + /// An observable that emits the current ViewModel and each later one. + /// + /// This follows the path the binding source generator emits for a property it cannot watch at compile time. + /// The registered with the highest affinity for the view type + /// watches the property. The property is named by a literal and read through the interface, so trimming + /// cannot remove anything this path needs. + /// + private static IObservable ObserveViewModel(IViewFor view) + { + var plugin = ObservationAffinityChecker.FindHigherAffinityPlugin(view.GetType(), nameof(IViewFor.ViewModel), 0, false); + if (plugin is null) + { + // Nothing can watch the property, so report its current value once. + return new ObservableMixins.DeferredValueObservable(() => view.ViewModel); + } + + System.Linq.Expressions.Expression> expression = static x => x.ViewModel; + return new PluginPropertyObservable( + plugin, + view, + expression.Body, + nameof(IViewFor.ViewModel), + static source => ((IViewFor)source).ViewModel, + false, + true); + } } diff --git a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net10.0-windows/PublicAPI.txt b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net10.0-windows/PublicAPI.txt index 90da29028c..feaf02484b 100644 --- a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net10.0-windows/PublicAPI.txt +++ b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net10.0-windows/PublicAPI.txt @@ -149,20 +149,13 @@ namespace ReactiveUI.Reactive extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.Reactive.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.Reactive.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.Reactive.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.Reactive.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net10.0-windows10.0.19041.0/PublicAPI.txt b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net10.0-windows10.0.19041.0/PublicAPI.txt index 929d5227a1..4bc599aaec 100644 --- a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net10.0-windows10.0.19041.0/PublicAPI.txt +++ b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net10.0-windows10.0.19041.0/PublicAPI.txt @@ -149,20 +149,13 @@ namespace ReactiveUI.Reactive extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.Reactive.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.Reactive.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.Reactive.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.Reactive.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net11.0-windows/PublicAPI.txt b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net11.0-windows/PublicAPI.txt index 90da29028c..feaf02484b 100644 --- a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net11.0-windows/PublicAPI.txt +++ b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net11.0-windows/PublicAPI.txt @@ -149,20 +149,13 @@ namespace ReactiveUI.Reactive extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.Reactive.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.Reactive.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.Reactive.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.Reactive.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net11.0-windows10.0.19041.0/PublicAPI.txt b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net11.0-windows10.0.19041.0/PublicAPI.txt index 929d5227a1..4bc599aaec 100644 --- a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net11.0-windows10.0.19041.0/PublicAPI.txt +++ b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net11.0-windows10.0.19041.0/PublicAPI.txt @@ -149,20 +149,13 @@ namespace ReactiveUI.Reactive extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.Reactive.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.Reactive.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.Reactive.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.Reactive.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net8.0-windows/PublicAPI.txt b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net8.0-windows/PublicAPI.txt index 90da29028c..feaf02484b 100644 --- a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net8.0-windows/PublicAPI.txt +++ b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net8.0-windows/PublicAPI.txt @@ -149,20 +149,13 @@ namespace ReactiveUI.Reactive extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.Reactive.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.Reactive.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.Reactive.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.Reactive.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net8.0-windows10.0.19041.0/PublicAPI.txt b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net8.0-windows10.0.19041.0/PublicAPI.txt index 929d5227a1..4bc599aaec 100644 --- a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net8.0-windows10.0.19041.0/PublicAPI.txt +++ b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net8.0-windows10.0.19041.0/PublicAPI.txt @@ -149,20 +149,13 @@ namespace ReactiveUI.Reactive extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.Reactive.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.Reactive.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.Reactive.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.Reactive.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net9.0-windows/PublicAPI.txt b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net9.0-windows/PublicAPI.txt index 90da29028c..feaf02484b 100644 --- a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net9.0-windows/PublicAPI.txt +++ b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net9.0-windows/PublicAPI.txt @@ -149,20 +149,13 @@ namespace ReactiveUI.Reactive extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.Reactive.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.Reactive.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.Reactive.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.Reactive.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net9.0-windows10.0.19041.0/PublicAPI.txt b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net9.0-windows10.0.19041.0/PublicAPI.txt index 929d5227a1..4bc599aaec 100644 --- a/src/ReactiveUI.Wpf.Reactive/PublicAPI/net9.0-windows10.0.19041.0/PublicAPI.txt +++ b/src/ReactiveUI.Wpf.Reactive/PublicAPI/net9.0-windows10.0.19041.0/PublicAPI.txt @@ -149,20 +149,13 @@ namespace ReactiveUI.Reactive extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.Reactive.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.Reactive.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.Reactive.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.Reactive.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf.Shared/WpfViewForMixins.cs b/src/ReactiveUI.Wpf.Shared/WpfViewForMixins.cs index 909a12a415..d893ea1062 100644 --- a/src/ReactiveUI.Wpf.Shared/WpfViewForMixins.cs +++ b/src/ReactiveUI.Wpf.Shared/WpfViewForMixins.cs @@ -4,7 +4,6 @@ // See the LICENSE file in the project root for full license information. using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Windows; @@ -35,7 +34,6 @@ public bool GetIsDesignMode() /// An that deactivates the view when disposed. /// Use this no-op overload purely to trigger activation when the /// view itself has no resources to manage — it avoids the empty WhenActivated(_ => { }) boilerplate. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public IDisposable WhenActivated() => item.GetIsDesignMode() ? EmptyDisposable.Instance @@ -44,7 +42,6 @@ public IDisposable WhenActivated() => /// Activates the specified WPF view and registers a block of disposables to be disposed when the view is deactivated. /// A function that returns disposables to be disposed when the view is deactivated. /// An that deactivates the view and disposes the registered disposables when disposed. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public IDisposable WhenActivated(Func> block) { ArgumentExceptionHelper.ThrowIfNull(item); @@ -57,7 +54,6 @@ public IDisposable WhenActivated(Func> block) /// A function that returns disposables to be disposed when the view is deactivated. /// An optional view instance to use for view model activation. /// An that deactivates the view and disposes the registered disposables when disposed. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public IDisposable WhenActivated(Func> block, IViewFor? view) { ArgumentExceptionHelper.ThrowIfNull(item); @@ -69,7 +65,6 @@ public IDisposable WhenActivated(Func> block, IViewFor? /// Registers a block of code to be executed when the specified WPF view is activated. /// An action that receives a callback for registering disposables. /// An that unregisters the activation logic. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public IDisposable WhenActivated(Action> block) { ArgumentExceptionHelper.ThrowIfNull(item); @@ -82,7 +77,6 @@ public IDisposable WhenActivated(Action> block) /// An action that receives a callback for registering disposables. /// The view instance to use for view model activation. /// An that unregisters the activation logic. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public IDisposable WhenActivated(Action> block, IViewFor view) { ArgumentExceptionHelper.ThrowIfNull(item); @@ -94,7 +88,6 @@ public IDisposable WhenActivated(Action> block, IViewFor vie /// Activates the specified WPF view and manages the provided disposables for the duration of the activation lifecycle. /// An action that receives a composite disposable for activation-related resources. /// An that unregisters the activation logic. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [MethodImpl(MethodImplOptions.AggressiveInlining)] public IDisposable WhenActivated(Action block) => item.WhenActivated(block, null); @@ -102,7 +95,6 @@ public IDisposable WhenActivated(Action> block, IViewFor vie /// An action that receives a composite disposable for activation-related resources. /// An optional view instance to use for view model activation. /// An that unregisters the activation logic. - [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public IDisposable WhenActivated(Action block, IViewFor? view) { ArgumentExceptionHelper.ThrowIfNull(item); diff --git a/src/ReactiveUI.Wpf/PublicAPI/net10.0-windows/PublicAPI.txt b/src/ReactiveUI.Wpf/PublicAPI/net10.0-windows/PublicAPI.txt index e70e55b322..df15c5f4ea 100644 --- a/src/ReactiveUI.Wpf/PublicAPI/net10.0-windows/PublicAPI.txt +++ b/src/ReactiveUI.Wpf/PublicAPI/net10.0-windows/PublicAPI.txt @@ -150,20 +150,13 @@ namespace ReactiveUI extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf/PublicAPI/net10.0-windows10.0.19041.0/PublicAPI.txt b/src/ReactiveUI.Wpf/PublicAPI/net10.0-windows10.0.19041.0/PublicAPI.txt index 6ed1f88598..5423078361 100644 --- a/src/ReactiveUI.Wpf/PublicAPI/net10.0-windows10.0.19041.0/PublicAPI.txt +++ b/src/ReactiveUI.Wpf/PublicAPI/net10.0-windows10.0.19041.0/PublicAPI.txt @@ -150,20 +150,13 @@ namespace ReactiveUI extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf/PublicAPI/net11.0-windows/PublicAPI.txt b/src/ReactiveUI.Wpf/PublicAPI/net11.0-windows/PublicAPI.txt index e70e55b322..df15c5f4ea 100644 --- a/src/ReactiveUI.Wpf/PublicAPI/net11.0-windows/PublicAPI.txt +++ b/src/ReactiveUI.Wpf/PublicAPI/net11.0-windows/PublicAPI.txt @@ -150,20 +150,13 @@ namespace ReactiveUI extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf/PublicAPI/net11.0-windows10.0.19041.0/PublicAPI.txt b/src/ReactiveUI.Wpf/PublicAPI/net11.0-windows10.0.19041.0/PublicAPI.txt index 6ed1f88598..5423078361 100644 --- a/src/ReactiveUI.Wpf/PublicAPI/net11.0-windows10.0.19041.0/PublicAPI.txt +++ b/src/ReactiveUI.Wpf/PublicAPI/net11.0-windows10.0.19041.0/PublicAPI.txt @@ -150,20 +150,13 @@ namespace ReactiveUI extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf/PublicAPI/net8.0-windows/PublicAPI.txt b/src/ReactiveUI.Wpf/PublicAPI/net8.0-windows/PublicAPI.txt index e70e55b322..df15c5f4ea 100644 --- a/src/ReactiveUI.Wpf/PublicAPI/net8.0-windows/PublicAPI.txt +++ b/src/ReactiveUI.Wpf/PublicAPI/net8.0-windows/PublicAPI.txt @@ -150,20 +150,13 @@ namespace ReactiveUI extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf/PublicAPI/net8.0-windows10.0.19041.0/PublicAPI.txt b/src/ReactiveUI.Wpf/PublicAPI/net8.0-windows10.0.19041.0/PublicAPI.txt index 6ed1f88598..5423078361 100644 --- a/src/ReactiveUI.Wpf/PublicAPI/net8.0-windows10.0.19041.0/PublicAPI.txt +++ b/src/ReactiveUI.Wpf/PublicAPI/net8.0-windows10.0.19041.0/PublicAPI.txt @@ -150,20 +150,13 @@ namespace ReactiveUI extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf/PublicAPI/net9.0-windows/PublicAPI.txt b/src/ReactiveUI.Wpf/PublicAPI/net9.0-windows/PublicAPI.txt index e70e55b322..df15c5f4ea 100644 --- a/src/ReactiveUI.Wpf/PublicAPI/net9.0-windows/PublicAPI.txt +++ b/src/ReactiveUI.Wpf/PublicAPI/net9.0-windows/PublicAPI.txt @@ -150,20 +150,13 @@ namespace ReactiveUI extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.IViewFor? view) { } } } diff --git a/src/ReactiveUI.Wpf/PublicAPI/net9.0-windows10.0.19041.0/PublicAPI.txt b/src/ReactiveUI.Wpf/PublicAPI/net9.0-windows10.0.19041.0/PublicAPI.txt index 6ed1f88598..5423078361 100644 --- a/src/ReactiveUI.Wpf/PublicAPI/net9.0-windows10.0.19041.0/PublicAPI.txt +++ b/src/ReactiveUI.Wpf/PublicAPI/net9.0-windows10.0.19041.0/PublicAPI.txt @@ -150,20 +150,13 @@ namespace ReactiveUI extension(TView item) where TView : System.Windows.FrameworkElement, ReactiveUI.Binding.IActivatableView { public bool GetIsDesignMode() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.IDisposable WhenActivated(System.Action block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action block, ReactiveUI.Binding.IViewFor? view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Action> block, ReactiveUI.Binding.IViewFor view) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public System.IDisposable WhenActivated(System.Func> block, ReactiveUI.Binding.IViewFor? view) { } } } diff --git a/src/examples/ReactiveUI.Builder.BlazorWasm/ReactiveUI.Builder.BlazorWasm.csproj b/src/examples/ReactiveUI.Builder.BlazorWasm/ReactiveUI.Builder.BlazorWasm.csproj index 30494d79f0..7d7c236442 100644 --- a/src/examples/ReactiveUI.Builder.BlazorWasm/ReactiveUI.Builder.BlazorWasm.csproj +++ b/src/examples/ReactiveUI.Builder.BlazorWasm/ReactiveUI.Builder.BlazorWasm.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/tests/ReactiveUI.Tests/Activation/ActivatingViewTests.cs b/src/tests/ReactiveUI.Tests/Activation/ActivatingViewTests.cs index 096c513d2a..b805632b3d 100644 --- a/src/tests/ReactiveUI.Tests/Activation/ActivatingViewTests.cs +++ b/src/tests/ReactiveUI.Tests/Activation/ActivatingViewTests.cs @@ -4,8 +4,10 @@ // See the LICENSE file in the project root for full license information. #if REACTIVE_SHIM +using ReactiveUI.Binding.Reactive.Fallback; using ReactiveUI.Reactive.Builder; #else +using ReactiveUI.Binding.Fallback; using ReactiveUI.Builder; #endif using Splat; @@ -248,6 +250,37 @@ public async Task SwitchingViewModelDeactivatesIt() } } + /// Verifies the view model still activates when no registered plugin can watch the view's ViewModel property. + /// A representing the asynchronous operation. + [Test] + public async Task ViewModelActivatesWhenNoPluginCanWatchViewModel() + { + var locator = new ModernDependencyResolver(); + locator.Register(static () => new ActivatingViewFetcher()); + + using (locator.WithResolver()) + { + ViewForMixins.ResetActivationFetcherCacheForTesting(); + ObservationAffinityChecker.Refresh(); + try + { + var vm = new ActivatingViewModel(); + var fixture = new ActivatingView { ViewModel = vm }; + + fixture.Loaded.OnNext(RxVoid.Default); + await Assert.That(vm.IsActiveCount).IsEqualTo(1); + + fixture.Unloaded.OnNext(RxVoid.Default); + await Assert.That(vm.IsActiveCount).IsEqualTo(0); + } + finally + { + ViewForMixins.ResetActivationFetcherCacheForTesting(); + ObservationAffinityChecker.Refresh(); + } + } + } + /// Provides a no-op activation callback for overload selection in tests. /// The activation-scoped disposable container. private static void NoopActivation(ActivationDisposables _)