question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Can't use App.xaml resources after Dependency Injection .NET MAUI

See original GitHub issue

Description

I have an application that uses mvvm pattern with Community Toolkit features. I am trying to use Dependency Injection to use an ApiService with its interface in my viewmodels, but after following the steps described here, I can’t access to App.xaml Resources (specifically colors), the intellisense works when I am writing code in XAML, but it doesn´t work after running. It is important to notice that I was using colors from resources correctly before trying to use Dependency Injection and changing the ViewModel - View linking method to the one described here, but I was unable to use ApiService. Here is my code.

Steps to Reproduce

App.xaml.cs (Login page is my first page):

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

LoginPage.xaml.cs

public partial class LoginPage : ContentPage
{
  public LoginPage(LoginPageViewModel loginPageViewModel)
  {
    BindingContext = loginPageViewModel;
    InitializeComponent();
  }
}

LoginPageViewModel

public LoginPageViewModel(IApiService apiService)
    {
        _apiService = apiService;
        Opacity = 1f;
        IsEnabled = true;
        IsRunning = false;
    }

LoginPage.xaml

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="NewScholarApp.Views.LoginPage"
         Title="LoginPage"
         xmlns:vm="clr-namespace:NewScholarApp.ViewModels"
         x:DataType="vm:LoginPageViewModel"
         BackgroundColor="{StaticResource GreenSchool}">

RegisterViews and ViewModels

public static MauiAppBuilder ConfigureViews(this MauiAppBuilder mauiAppBuilder)
    {
        mauiAppBuilder.Services.AddTransient<LoginPage>();

        return mauiAppBuilder;
    }

public static class RegisterViewModels
{

    public static MauiAppBuilder ConfigureViewModels(this MauiAppBuilder mauiAppBuilder)

    {
        mauiAppBuilder.Services.AddSingleton<LoginPageViewModel>();

        return mauiAppBuilder;
    }
}

Link to public reproduction project repository

https://github.com/luis95gr/SampleProject

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

Android, I was not able test on other platforms

Affected platform versions

Android 12.1

Did you find any workaround?

Don’t use any StaticResource

Relevant log output

Microsoft.Maui.Controls.Xaml.XamlParseException: 'Position 8:14. StaticResource not found for key GreenSchool'

Issue Analytics

  • State:open
  • Created 10 months ago
  • Reactions:5
  • Comments:19 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
symbiogenesiscommented, Mar 5, 2023

What is happening is that if you use DI to register ContentPage elements and maybe other UI elements, you will not be able to access static resources declared in your App.xaml file. I’m sure the technical reasons involve the app lifecycle assumptions deep within MAUI. A UI element resolved via constructor injection is initialized very early in the app or page lifecycle, and it can only access those resources later on. I believe I saw other bugs also logged about this, and maybe it will get fixed.

But essentially you can get around this by injecting IServiceProvider into the App class, and then using that to resolve the MainPage inside the App class, thereby forcing the resolution of the page element to occur later than the constructor injection would’ve resolved it. I demonstrated this approach in the comment above yours.

Another benefit of that approach is if you were injecting multiple modals/elements/popups into the same class, you would be able to ensure that those modals/elements/popups were only instantiated if needed, and only when they are needed. So you could paint the screen quicker, use less memory, etc.

3reactions
symbiogenesiscommented, Mar 5, 2023

I encountered this same issue when upgrading to MAUI and switching to the new DI style. This is a bug.

The options for workarounds I found are the following:

  1. Best: Inject IServiceProvider and use that to resolve the page only at the moment it is needed.
  2. Worse: For the App’s MainPage, inject only the ViewModel, not the page, and new-up the page. (Lose DI for the page)
  3. Even Worse: Inject the main page using System.Lazy as described here or here
  4. Worst of all: Convert all StaticResources in App.xaml to DynamicResources and incur the cost of doing that.
Read more comments on GitHub >

github_iconTop Results From Across the Web

Can't use App.xaml resources after Dependency Injection . ...
I am trying to use Dependency Injection to use an ApiService with its interface in my viewmodels, but after following the steps described...
Read more >
NET MAUI App Stopped Working -- HELP!
The trick to this solution is to add a name to your component, then use the Source attribute to reference the item. It...
Read more >
Improve app performance - .NET MAUI
Learn how to increase the performance of .NET MAUI apps by reducing the amount of work being performed by a CPU, and the...
Read more >
Make the IServiceProvider of your MAUI application ...
In this post, I will show you how you can make the default IServiceProvider of your MAUI application accessible via the MVVM CommunityToolkit's...
Read more >
What does a production MAUI app look like? - Kael's Kabbage
Here's a few tips and tricks and common patterns for a MAUI app that I ... first view can't have constructor injection for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found