'.Net MAUI - AppShell navigation & dependency injection

I'm playing around with .Net Maui, AppShell and dependency injection.

I try to call a page with a constructor which takes the ViewModel of this page as parameter.

The constructor looks like this:

public AuthenticationPage(AuthenticationViewModel viewModel)
{
    InitializeComponent();
    BindingContext = viewModel;
}

In my MauiProgram.cs I registered both, the page and the VM

builder.Services.AddSingleton<AuthenticationViewModel>();
builder.Services.AddSingleton<AuthenticationPage>();

My App.xaml.cs looks like this:

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
        MainPage = new AppShell();
    }
}

And my AppShell.xaml looks like this:

<Shell  xmlns="http://schemas.microsoft.com/dotnet/2021/maui" 
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
           xmlns:pages="clr-namespace:DeepBlue.Pages"
           xmlns:auth="clr-namespace:DeepBlue.Pages.Authentication"
           x:Class="DeepBlue.AppShell">

    <!-- Login and Registration Page -->
    <ShellContent Route="login"
                  ContentTemplate="{DataTemplate auth:AuthenticationPage}">
    </ShellContent>

    <!-- Main Page -->
    <FlyoutItem Route="main"
                FlyoutDisplayOptions="AsMultipleItems">
        <ShellContent Route="dashboard"
                      ContentTemplate="{DataTemplate pages:DashboardPage}"
                      Title="Home" />
    </FlyoutItem>

</Shell>

Now when I execute my Project, I get the following error:

System.MissingMethodException: 'No parameterless constructor defined for type 'DeepBlue.Pages.Authentication.AuthenticationPage'.'

Could someone please tell me why the dependency injection does not work in this case?

If I don't implement the AppShell, everthing is working fine.... I can call AuthenticationPage as MainPage via injection from my App.xaml.cs like this:

public App(AuthenticationPage page)
{
    InitializeComponent();
    MainPage = page
}

Thanks, Phil



Solution 1:[1]

Shell (and DataTemplates that is associated) does not have support for dependency injection (yet). Issues on the repository are opened here and here. And at the time of writing this answer a PR is open that adds this functionality. You can track the progress of that here.

Solution 2:[2]

The Maui DevBlogs of January 2022 suggested that this was implemented, but it seems like it is partly removed temporary because of some issues. For now there is a workaround: Add the view which needs DI in the services in MauiProgram.cs:

// Workaround for Shell/DataTemplates:
builder.Services.AddTransient<MainPage>();
builder.Services.AddTransient<AuthenticationPage>();

Hopefully DI support for Shell and DataTemplates will be implemented soon correctly.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Gerald Versluis
Solution 2 Marcel Wolterbeek