Reputation: 490
I've got a service A that is shared among various components. That service needs to be initialized at startup with values from a WebApi.
How can I accomplish that? I tried two things.
_1.
In program.cs/main method I do
builder.Services.AddScoped
with A and other services B and C.
Then I call a method
async LoadSetupData(wasmBuilder)
which gets services A, B, C via
wasmBuilder.GetRequiredService<T(A)>...
and then
A.MySetupValues = await B.GetSetupValues().
The values are retrieved through the WebApi.
That works so far. But when I use A in a component via [Inject] A a, the service object I get is not the one I retrieved in LoadSetupData (service has a Guid property, they are different).
_2.
I tried adding A by providing a factory method to AddScoped. That doesn't work because getting Values from a WebApi is intrinsically asynchronous. And asynchronous calls can't be used from program.cs/main ("Cannot wait on monitors on this runtime").
Thank you very much for reading! Any help is highly appreciated!
Upvotes: 2
Views: 4459
Reputation: 490
Thanks for all of your answers! I was able to resolve the problem by doing the Initialization in the App Component in OnInitializedAsync.
[Inject] IServiceProvider sp { get; set; }
protected override async Task OnInitializedAsync() {
ISvcB svcb = sp.GetRequiredService<ISvcB>();
ISvcA svca = sp.GetRequiredService<ISvcA>();
svca.SetupData = await svcb.GetSetupData();
}
Upvotes: 3
Reputation: 2800
Try to redefine your design.
I prefer to have all the initialization of the service in the constructor.
You need some other services (B & C), so you need to use DI in the constructor of the service A.
I think the following design should work for your case:
builder.Services.AddScoped<IServiceA,ServiceA>();
var hostInstance = builder.services.Build();
var theServiceA = hostInstance.GetRequiredService<IServiceA>();
...
hostInstance.RunAsync()
Try this one in alternatives:
builder.Services.AddScoped(sp => sp.GetRequiredService<IServiceA>().LoadSetupData());
Just a note to anyone, in Blazor WASM Scoped and Singleton life time are the same. Not in Server.
Upvotes: 0
Reputation: 6306
In the Program.cs you can load your data and then indicate how to resolve the dependancy injection.
var datas = await (new TheProvidingDataService()).LoadDataAsync();
builder.Services.AddSingleton(s => new NeedYourDataService(data));
Upvotes: 2