Problem Description
I am developing a MAUI app that utilizes Shell tabs alongside a login flow. Each tab’s page and corresponding ViewModel are registered as singletons. Upon the initial load, the pages use the OnAppearing
method to call an initialization method from the ViewModel, which fetches data from a local database (using LiteDb) and loads it into an observable collection for the user to view.
Issue Encountered
The application allows the current user to log out, with the following flow:
try
{
SecureStorage.Default.RemoveAll(); // Clears the session of the logged-in user
await _repositories.ClearAsync(); // Clears all data created by the current user
await Shell.Current.GoToAsync($"//{nameof(SignInUpPage)}");
}
catch (Exception)
{
Toast.Show("Something went wrong");
}
After navigating back to the SignInUpPage
and logging in again, the data from the previous session is still visible on the main tab pages. This is due to the pages and ViewModels being registered as singletons.
Question
What is the best approach to ensure that these pages and ViewModels are destroyed or reinitialized upon a new login? The goal is to have fresh instances that reload data appropriately when a user logs in after logging out.
Page setup
In the MainShellPage.xaml I have the following:
<ShellContent
Title="Loading"
ContentTemplate="{DataTemplate pages:LoadingPage}"
Route="LoadingPage" />
<ShellContent ContentTemplate="{DataTemplate account:SignInUpPage}" Route="SignInUpPage" />
<TabBar Route="MainShellPage">
<Tab Title="{Binding Dashboard.Title}" Icon="{Binding Dashboard.Icon}">
<ShellContent ContentTemplate="{DataTemplate dashboard:DashboardMainPage}" />
</Tab> Another tabs .. </TabBar>
When LoadingPage starts in its own viewmodel it decides if the user is authenticated or not.
If user is authenticated it goes to:
await Shell.Current.GoToAsync($"//{nameof(MainShellPage)}")
Otherwise
await Shell.Current.GoToAsync($"//{nameof(SignInUpage)}")
The reason of the Loading page:
I swiched the all tabs pages and viewmodels to transients, and when logout happnes I do the following to reinit MainPage.
try
{
SecureStorage.Default.RemoveAll(); // Clears the session of the logged-in user
await _repositories.ClearAsync(); // Clears all data created by the current user
App.Current.MainPage = new MainShellPage(); // Reinit main page -> when login again all pages and vms will be reinit
await Shell.Current.GoToAsync($"//{nameof(SignInUpPage)}");
}
catch (Exception)
{
Toast.Show("Something went wrong");
}