Search code examples
dependency-injectionblazor

How do I share state to be injected across components rendered in different render modes in blazor .net 8?


I am a little confused with this dual project setup in .net8, specifically around DI and sharing state between different render modes.

Now, take this example service

public class GuidService
{
    public Guid Guid { get; } = Guid.NewGuid();
}

Adding that as a singleton in the client project and scoped in the server project, I get different values for it depending on whether the component is rendered as static SSR, interactive server, or interactive WASM.

enter image description here

Also in addition, when I navigate away (within the same app, not leaving or refreshing) from this page and come back, the GUID shown for interactive WASM and interactive Server remain the same as they were previously, which I expect. What I didn't expect however is that the static SSR component will get a new Guid each time I navigate to a different page and come back.


Solution

  • You need to think three different applications with some twists.

    1. Static SSR and Active SSR share Singleton services.
    2. The Static SSR Scoped Service container only exists for the duration of the Http request. Standard server side asp/razor/mvc/api behaviour.
    3. Active SSR scoped service exists for the duration of the SPA session, one per Blazor Hub session.
    4. CSR Scoped and Singleton services exist for the scope of the SPA. There's no real difference between Scoped and Singleton.

    You can pass pre-render state from SSSR to the SPA. See - https://learn.microsoft.com/en-us/aspnet/core/blazor/components/prerender?view=aspnetcore-8.0#persist-prerendered-state.

    Otherwise, as Brian Parker suggests you need to think stateless or persist state outside the application context.

    There's my commentary on the topic here: https://github.com/ShaunCurtis/Blazor.ExploreRendering/blob/master/Documents/Going-For-Broke.md