Mister Cook
Mister Cook

Reputation: 1602

How to retrieve a value from server once and store for lifetime of Blazor WASM application?

When my Blazor application first loads I want to to get a value from the server and use this value for the the lifetime of the application.

This value should only be retrieved once via an async HttpClient call. My approach so far is to create an interface that can obtain and return this loaded value:

public interface IMyGlobal
{
    public Task Initialise();

    public string Value { get; set; }
}

Then in my implementation

public class MyGlobal : IMyGlobal
{
    private readonly HttpClient _httpClient;

    public MyGlobal (HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    private async Task<Response> GetMyValue()
      { // This just loads it from a web-service asynchronously - removed for simplicity }

    public async Task Initialise()
    {
        var response = await GetMyValue();

        _value = response.Value;
    }

    public string Value
    {
        get => _value;
        set => _value;
    }

    private string _value;
}

In Program.cs, I register this service with:

builder.Services.AddHttpClient<IMyGlobal, MyGlobal>():

And I can then inject it into my components wherever I need it with the intention that Value can be obtained throughout my application.

However, I need to call Initialise, should this be done in Program.cs? If yes how?

(I tried to lazy-load it from the property getting, but as the Value has to be obtained asynchronously that doesn't work.)

Upvotes: 1

Views: 250

Answers (1)

Kirk Woll
Kirk Woll

Reputation: 77616

Based on your comments, I understand what was tripping you up. There are a variety of ways to register a service, but for your scenario, I'd go with the overload that allows you to register the (naturally singleton) instance of the service directly. So instead of this:

builder.Services.AddHttpClient<IMyGlobal, MyGlobal>():

Replace it with something along the lines of:

var serviceProvider = builder.Services.BuildServiceProvider();
var myGlobal = new MyGlobal(serviceProvider.GetService<HttpClient>());
await myGlobal.Initialize();
builder.Services.AddSingleton<IMyGlobal>(myGlobal);

Now, whenever you request an instance of IMyGlobal it will return your (initialized) instance of MyGlobal.

Upvotes: 1

Related Questions