In Blazor, automatic dependecy injection via constructor works as follows:
// ---- Method A: AUTOMATIC SERVICE DI ----//
IMyOtherService _otherService;
public class MyService(IMyOtherService oService) {
_otherService = oService;
}
public async Task DoSomethingFromOtherService() {
await _otherService.DoSomething();
}
The services are registered as follows:
services.AddSingleton<MyOtherService>();
services.AddSingleton<MyService>();
The above structure works fine and services are created when first used by the app.
It is also possible to inject the IServiceProvider
to MyService
and retrieve the required IMyOtherService
WHEN NECESSARY as follows:
// ---- Method B: IServiceProvider INJECTION ----//
IServiceProvider _serviceProvider;
public class MyService(IServiceProvider serviceProvider) {
_serviceProvider = serviceProvider;
}
public async Task DoSomethingFromOtherService() {
await serviceProvider.GetService<IMyOtherService>().DoSomething();
}
// --- register services as follows:
services.AddSingleton<MyOtherService>();
services.AddSingleton<MyService>(provider => new MyService(provider));
I see a few advantages of Method B over Method A:
- we can retrieve services when required on the fly without having to modify constructors,
- (code readability)no need to write long constructors if there are many dependencies.
The drawback of Method B is that we need to ensure the service exists, which Method A does implicitly when actually creating the service instances.
I have the intuition that Method B is a way better tradeoff though. As it is NOT standard in the doc, I am wondering why it is not the suggested way. Is there a specific reason I am missing towrads NOT TO USE METHOD B?