Aspnetcore: Support HostedServices in Blazor

Created on 2 Feb 2019  路  11Comments  路  Source: dotnet/aspnetcore

The wire up for the HostedServiceExecutor is missing in Blazor.

affected-very-few area-blazor enhancement severity-major

Most helpful comment

I'm listening for SignalR Notifications in the Background.

All 11 comments

What do you need this for? We intentionally don't pull in these dependencies and we don't currently plan to do so because of the size impact.

I'm listening for SignalR Notifications in the Background.

We should figure out if we can refactor some of the abstractions assemblies to lessen the impact. It would be unfortunate to introduce an IHostedService light into Blazor apps specifically. One solution might be to move the IHostedService definition to another assembly (but I鈥檓 just brainstorming here)

Another option is to setup and tear down the background service on the root component

We should figure out if we can refactor some of the abstractions assemblies to lessen the impact.

The big ones to address - banish FileProviders into the nether realm - it's not useful in our context and is just bloat. Get rid of the dependency of Configuration -> Primitives.

The big ones to address - banish FileProviders into the nether realm - it's not useful in our context and is just bloat. Get rid of the dependency of Configuration -> Primitives.

If we could avoid breaking too much that would be best. Is it the primitives reference causing most of the problems?

Yes.

Another way to think of this might be to provide a sample of how to make a "generic host Blazor app". I'm still pretty concerned even if we get this down to like 50kb and include it on the default path.

OK lets at least try to work on it. I know you spent some time here but we have more time in 3.0.

Another option is to setup and tear down the background service on the root component

This seems like the best option right now. It is then possible to render an initial GUI with some loading indicator.

Something like this can be used

    <div class="main-content">
        @if (!hasConnection) {
          <Heading Size="HeadingSize.Is2">Setting up server connection</Heading>
        }
        else {
            @Body
        }
    </div>


@code {
    bool hasConnection = false;

    protected override async Task OnInitializedAsync() {
        // Start signalR client here instead of Program.cs to avoid blocking with `Loading...` screen
        hasConnection = false;
        await client.Start();
        hasConnection = true;
    }
}

Hosted services could be an optional package, and work similar to @koliyo explained but is a component you can add in App.razor or your main layout:

The component could look something like:

@inject IEnumerable<IHostedService> HostedServices
@implements IDisposable

 //[Display Child Content Here Shown Whilst Starting Services]
@ChildContent

code
{
    protected override async Task OnInitializedAsync()
    {     
          var cts = new CancellationTokenSource();
          await Task.WhenAll(HostedServices.Select(s => s.StartAsync(HostedServicesCancellationToken.Token)));
    }

    public void Dispose()
    {
          // make sure services are stopped...
    }
}

As far as I can tell all you'd need is a package containing:

  1. This Blazor component
  2. IHostedService interface

Users would add the above component to App.razor or MainLayout, and then just register some IHostedService's in Program.cs

Some areas of slight concern though - I don't think the Blazor WebAssembly Host has a clear concept of a lifetime, with cancellation tokens etc.

  1. If possible, I'd like to have the ability / chance, to signal hosted services to stop before the web assembly application was reloaded i.e via a page reload() or a browser tab close().
Was this page helpful?
0 / 5 - 0 ratings