[Enhancement] Support IInitialize with Dialog ViewModel
Summary
In addition of the IDialogAware, provide a Dialog ViewModel initialization, similar of IInitialize and IInitializeAsync of page navigation.
API Changes
Add the equivalent of IInitialize & IInitializeAsync interfaces for the Dialogs.
public interface IDialogInitialize
{
void Initialize(IDialogParameters parameters);
}
public interface IDialogInitializeAsync
{
Task InitializeAsync(IDialogParameters parameters);
}
Intended Use Case
Support the synchronous and asynchronous initialization of a Dialog ViewModel.
Please explain what the benefit / scenario is that you hope to solve here? I'm assuming you are used to Forms/MAUI Page Navigation hence the request. Dialogs and Page Navigation work differently. There is in fact no actual need for an "Initialize" interface.
- Dialogs are Navigated to once and then closed, while Pages can be Navigated to and then Navigated Back to...
- The existing API already initializes the Dialog before it is presented.
Thanks for the feedback, @dansiegel. I understand the distinction between Dialogs and Page Navigation, but my suggestion is focused on supporting asynchronous initialization. The current IDialogAware only supports synchronous operations, which can be limiting for scenarios that require async tasks before displaying the Dialog.
Introducing IDialogInitializeAsync would address this need and create consistency with the IInitializeAsync interface used in Page Navigation.
Alternatively, reusing the IInitializeAsync interface for Dialogs could be considered, but it would introduce a breaking change, as the parameter type would need to change from INavigationParameters to IParameters.
There is a major drawback to an async interface when showing a dialog. If you make a call to a service or perform some other async operation, the Dialog will not show until that operation is completed, which can cause some very bad user experiences. Imagine clicking a button to show a dialog, but first a network call is made before the dialog is shown, there will be a noticeable delay from when the button was pushed to when the dialog was shown. Of course, the first instinct will be to blame Prism, when in actuality it's the async nature of the code.
We had this exact same problem when we provided support for the IInitializeAsync for navigation. Suddenly everyone's navigation started to lag and feeling "slow". Of course, Prism got the blame but turns out it was their code in the Async interface that was causing the issues because the navigation couldn't complete until their async code finished.
Why do you want to have the dialog wait on a task before opening? Why not show the dialog immediately and show a loading indicator when making any async calls you need. This way your UI stays very responsive.
Thanks for the explanation. I understand the concern about delays with async dialogs, but since IInitializeAsync is already used in navigation, it’s about consistency. If we allow async initialization for navigation, it makes sense to offer the same for dialogs.
In my case, the async task is brief, and I currently have to use async void OnDialogOpened, which I want to avoid. I agree that long tasks should be handled with loading indicators, but having InitializeAsync for dialogs would provide a consistent pattern for developers to use when appropriate.
Trying to have consistency with patterns that are not recommended, and can actually be a trap, isn't a good reason to add a new API.
What is your main concern with async void? Is there technical concern or does it just make you feel weird because you always hear the "don't use async void" mantra?
Trying to have consistency with patterns that are not recommended, and can actually be a trap, isn't a good reason to add a new API.
I totally agree, but then if the IInitializeAsync is not recommended, what is the alternative/recommendation? Fire and forget a Task in the constructor? Fire and forget a Task in the void Initialize?
What is your main concern with
async void? Is there technical concern or does it just make you feel weird because you always hear the "don't use async void" mantra?
As mentioned, the Task I execute is very short, some milliseconds. So there is no noticeable delay on the user experience. In this case, it's better to load it before the view is displayed, that avoid a re-render in a very short time that can produce blinks in the view. And yes, if we can avoid the async void, that's a cosmetic extra point.
I totally agree, but then if the IInitializeAsync is not recommended, what is the alternative/recommendation? Fire and forget a Task in the constructor? Fire and forget a Task in the void Initialize?
Yes, async void is a perfectly valid paradigm. It's used in events and commands. I didn't even want to add the IInitializeAsync because what I feared would happen did indeed happen. And the same thing will happen with dialogs.
To be clear, I'm not against adding it, I'm just having a hard time being convinced it should be added.
Are you by chance a Commercial Plus license holder?
Are you by chance a Commercial Plus license holder?
Yes
I can't find your account. Connect with us on our Discord to discuss.