Server-side Blazor state management


One of the more interesting things about server-side Blazor is that, unlike all previous UI frameworks, it maintains all per-user state (including the user's identity) in a dependency injection scope.


Windows Forms, WPF, and UWP use the current thread. ASP.NET normally uses HttpContext. Blazor WebAssembly is similar to WinForms/WPF - a single process space for the user and app.


But server-side Blazor is stateful on the server, so it can't rely on HttpContext, or any specific thread. So the way they implemented management of things like the current user's principal/identity is via DI scope. Each server-side Blazor app is hosted in its own DI scope, and so a service added as a scoped service is exactly what is necessary to maintain any per-user information.


The downside to this, is that if you (like me) have any static methods that, for example, check the user's permissions based on user identity - well, that's impossible. It is impossible because the user's identity isn't "ambient" like in all other UI frameworks. The user's identity is only available in an _instance_ of a type, and only if a service that has the user identity was injected into your instance!


As a result, I've spent many, many hours over the past couple weeks rewriting the #cslanet framework so it gets the user identity via DI, and then passes the identity around to all objects that need it (which is a lot - CSLA is primarily a rules engine, so the user identity is necessary all over the place).


It turns out that DI, like async/await, is like a virus. Once you start using it a little, pretty soon you find that you've had to rewrite nearly all your code to rely on the concept.   

1 Reply
The good news is the the .razor page always *does* know who the current user is.
When calling .cs code, yes, I do need to pass the identity of the current user.