-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Maybe this is not really a bug, but I think it might be worth investigating, since I'm a little confused about it.
Describe the bug
After upgrading to the latest ReactiveUI(16.3.10) I noticed that ReactiveCommand CanExecute is always false - the button is disabled. Even if you don't pass IObservable<bool> canExecute in the ReactiveCommand the button still won't be active.
This problem started after >14.1.1 and higher due to these PRs(#2880, #2835). Roll backing the changes returns everything to normal.
However, this happens under certain combination.
The combo is
- Wpf
- ReactiveUI >14.1.1 and higher
- Dapplo.Microsoft.Extensions.Hosting(in repro I used slightly modified own solution)
- SimpleInjector
Steps To Reproduce
https://github.com/ScarletKuro/ReactiveCommandSideEffect
Sorry for maybe not for the most minimalistic repro, but it took me hours to find the issue and remove everything extra from not the smallest production application.
My observation
- If we remove
CustomerInputViewModelfrom DI the problem is gone. - If we remove
BrushfromCustomerInputViewModelproperties the problem is gone. - If we remove
SimpleInjectors.Verify(in RootBoot) method from container booting then the problem is gone. - If we move
SimpleInjectors.Verifymethod to UI thread the problem is gone.
My thoughts
The SimpleInjector has diagnostic service which is really helpful. In short, it will iterate thought all registrations and check for lifestyle mismatches etc. For this it has to resolve the types first and this might happen not on UI thread which will have a side effect on ReactiveCommand.
My question is, why does this happen. Like alright, the check might not run on UI, but since the ViewModels registered as transient and when View is created(also always a new object) it will resolve the ViewModel under the correct UI thread, which is easy to check, as well as the form is running on the correct thread, otherwise the form would not show up. Also pay attention that if we remove the second ViewModel(CustomerInputViewModel or Brush properties) which doesn't even have a view it will start to work, how can these two separate ViewModel objects affect each other(CustomerInputViewModel has effect on Main2ViewModel). This is a really weird side effect for me, which might affect other users that has not "standard" application architecture.
As current solution, I moved SimpleInejectors verification in method that runs in UI thread.