[Bug] Dependency Injection is not correctly setup by extensions AddBlazoredLocalStorage
See original GitHub issueDescribe the bug
The dependency injection is not correctly set up by the AddBlazoredLocalStorage
extension methods.
To Reproduce
The following program injects a null version of the LocalStorageService storage
variable into the constructor for StateService
:
public class Program {
public static async Task Main(string[] args) {
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddTransient(sp => new HttpClient {
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
});
builder.Services.AddBlazoredLocalStorage();
builder.Services.AddSingleton<StateService>(sp => {
var storage = sp.GetService<LocalStorageService>();
return new StateService(storage);
});
await builder.Build().RunAsync();
}
}
Expected behavior
The LocalStorageService storage
should not be null but instead be an instance of the LocalStorageService
type.
Screenshots If applicable, add screenshots to help explain your problem.
Hosting Model (is this issue happening with a certain hosting model?):
- Hosted Blazor WebAssembly
I have not tried this on the other hosting models.
Additional context
The program can be made to work if it is changed to not use the AddBlazoredLocalStorage
extension methods but instead create the LocalStorageService
instance it self like this:
public class Program {
public static async Task Main(string[] args) {
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddTransient(sp => new HttpClient {
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
});
builder.Services.AddSingleton<LocalStorageService>(sp => {
var runtime = sp.GetService<IJSRuntime>();
var options = sp.GetService<IOptions<LocalStorageOptions>>();
return new LocalStorageService(runtime, options);
});
builder.Services.AddSingleton<StateService>(sp => {
var storage = sp.GetService<LocalStorageService>();
return new StateService(storage);
});
await builder.Build().RunAsync();
}
}
Issue Analytics
- State:
- Created 3 years ago
- Comments:10 (5 by maintainers)
Top GitHub Comments
Firstly, singleton and scoped are the same in Blazor WebAssembly. I wrote a blog post coving this in some detail a couple of years ago, it might be worth a read.
Outside of Blazor the specific reason you can’t inject a scoped service into a singleton is that it would break the lifetime expectation of the scoped service. In a ASP.NET Core WebAPI app a scoped service is tied to the lifetime of the request, where as a singleton is tied to the lifetime of the application. If you were allowed to inject the scoped service into the singleton, it would no longer be scoped as it would persist for the lifetime of the singleton instance it was being injected into.
I hope that makes sense. As this isn’t a bug I’m going to close the issue but I’m happy to answer any more questions you have on the subject.
Sorry I didn’t saw it… My google search bring me here.
Thank you for you’re quick response !