I have 2 possible implementations of an interface, and in my Program.cs I want to dynamically inject the right one. However, the logic of which one to inject depends on another service being used. Previously in I was doing this:
services.AddScoped<IOtherService, OtherService>();
var serviceProvider = services.BuildServiceProvider();
var otherService = serviceProvider.GetRequiredService<IOtherService>();
if (otherService.SomeValue == "Value1")
{
services.AddScoped<IDynamicService, DynamicService1>();
}
else if (otherService.SomeValue == "Value2")
{
services.AddScoped<IDynamicService, DynamicService2>();
}
This gives a warning that BuildServiceProvider() shouldn’t be called like this because it could result in an additional copy of singleton services being created. I found several answers on the Internet (example) saying that the solution is to use the Options Pattern and AddOptions().Configure(), but I can’t quite understand how that works in my case.
Using this example:
services.AddOptions<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme)
.Configure<IManageJwtAuthentication>((opts,jwtAuthManager)=>{
opts.TokenValidationParameters = new TokenValidationParameters
{
AudienceValidator = jwtAuthManager.AudienceValidator,
// More code here...
};
});
This seems to sets up some configuration details on the injected IManageJwtAuthentication. But I don’t need to just configure some property on my injected service, I need to change what service is being injected. I don’t see how I can do something like the example above unless this Configure() method could also be passed my IServiceCollection so that I can call services.AddScoped() from within that context. In a few different attempts at similar things, I wasn’t ever seeing my .Configure() method called at all.
Am I right that Options Pattern is the way to go for something like this? I don’t quite understand the relationship between Options Pattern and accessing other services from within my Program.cs; what I’ve read suggests that Options Pattern is a way to load and inject subsets of Configuration/settings.