How to use AddScope in Blazor .NET 8

Gabriel 5 Reputation points
2024-06-18T13:29:52.3533333+00:00

I am currently learning Blazor in .NET 8 (server) and I'm having trouble understanding a key concept. I need to have a persistent service per user, so I can't use a singleton. The thing that makes sense is a scope, from all the stuff I've read online (and from Microsoft docs), it should work, people used to build TransferServices with that! However, the thing is it doesn't work as I expect; it's like every component has a different "services."

Here is the code of my MainLayout (yes, I know Dispose is not implemented):

public partial class MainLayout : LayoutComponentBase
{
    [Inject] 
    private ThemeService ThemeService { get; set;} = default!;
    private string CurrentTheme { get; set; } = "";

    protected override void OnInitialized()
    {
        ThemeService.OnThemeChanged += OnThemeChanged;
        CurrentTheme = ThemeService.GetThemeString();
    }
    private void OnThemeChanged(string p_theme)
    {
        CurrentTheme = p_theme;
        Console.WriteLine("Theme changed to " + p_theme);
        
    }
}

And here is the code of my UI element far away from my MainLayout that allows me to change the theme:

public partial class ThemeSelector : ComponentBase
{
    [Inject] 
    private ThemeService ThemeService { get; set;} = default!;
    private void DarkThemeChanged(bool p_isThemeDark)
    {
        ThemeService.IsDarkTheme = p_isThemeDark;
    }
}

Basically, in ThemeSelector and in MainLayout, ThemeService is different. I'm using Blazor .NET 8 Auto, but all that code is in the server, not in the .Client. Am I not understanding something? (Sorry for my poor English; it's not my first language.)

Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,477 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 60,361 Reputation points
    2024-06-18T19:31:48.9066667+00:00

    .AddScope() with a Blazor app, is for the life the Blazor app. But your components will not rerender just because an injected service changed or fired an event. You must call StateHasChanged() from the event. But the is poor design. you should be using a cascading state variable. rather than having every component listen for the change, and then fire a tree render(). typically this would all be managed in a component close to the root.