Skip to content

Reconsider static JSRuntime.Current #6828

@SteveSandersonMS

Description

@SteveSandersonMS

JSRuntime.Current is misleading. People commonly write code like this:

public override void OnInit()
{
    StocksService.OnStockTickerUpdated += stockUpdate =>
    {
        JSRuntime.Current.InvokeAsync<object>(
            "handleTickerChanged", stockUpdate.symbol, stockUpdate.price);
    };
}

This is fine for client-side code, but when executing on the server, which user's browser is it sending the handleTickerChanged call to? The developer probably thinks it's the user whose browser is rendering the component that contains this call, but that's not true. In fact, it depends on the async context in which the OnStockTickerUpdated event fires - maybe it's some other user who caused the event, or maybe it's nobody at all. When testing locally there's a good chance it seems to work, but the problem of sending the call to the wrong user only surfaces in production when there is more than one user.

The underlying problem is having a static JSRuntime.Current. If, instead, you could only acquire the IJSRuntime from DI, then each component would get and store the right instance for its user, and the call would always be sent to the right user. It's already possible to get the IJSRuntime from DI, but people don't realise that's what they should do so they continue to use JSRuntime.Current.

Proposal: Just remove the static JSRuntime.Current, so you can only get it from DI.

Drawback: in the pure client-side Blazor scenario, this complicates things for library code that doesn't necessarily have access to DI. It forces the developer to obtain the IJSRuntime from DI and pass it into the library somehow. However I still think this is the right thing to do, because if libraries are ever going to work in both client and server code, they have to let the developer pass the IJSRuntime into them.

Metadata

Metadata

Assignees

Labels

DoneThis issue has been fixedarea-blazorIncludes: Blazor, Razor ComponentsenhancementThis issue represents an ask for new feature or an enhancement to an existing one

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions