Last active
November 15, 2020 19:22
-
-
Save ericsampson/bb37bd6da0748af2e928ee750563452a to your computer and use it in GitHub Desktop.
Configuration pattern and ConfigureServices
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// I have a service that needs to be initialized with a FooOptions and then added to the DI container. | |
// I also want to have IOptions<FooOptions> in the DI container to allow injection in other methods. | |
// How should I write my AddFoo extension method to support this? | |
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.AddFoo(fooOptions => | |
{ | |
configuration.GetSection("FooOptions").Bind(fooOptions) | |
fooOptions.param = "override"; | |
}); | |
} | |
namespace Microsoft.Extensions.DependencyInjection | |
{ | |
public static class MyFooExtensions | |
{ | |
public static IServiceCollection AddFoo(this IServiceCollection services, | |
Action<FooOptions> setupOptions) | |
{ | |
services.Configure<FooOptions>(setupOptions); | |
services.AddSingleton<IFoo>(sp => | |
{ | |
var options = sp.GetRequiredService<IOptions<FooOptions>>(); | |
return new FooFactory(options.Value); | |
}; | |
return services; | |
} | |
} | |
} |
@andrewlock, argh I'm an idiot. The signature is FooFactory(FooOptions options)
, not an IOptions<FooOptions>
, if that helps.
I think I've revised the AddFoo()
code in a way that should work now?? Or not...
I found a helpful blog post from @TsuyoshiUshio that gave me the idea:
https://medium.com/@tsuyoshiushio/servicecollection-di-with-optional-settings-fc4ee46984d1
@ericsampson That looks very similar to my suggestion, with a slight tweak. I don't think your suggestion will quite work though. Try this instead:
public void ConfigureServices(IServiceCollection services)
{
services.AddFoo(fooOptions =>
{
configuration.GetSection("FooOptions").Bind(fooOptions)
fooOptions.param = "override";
});
}
Thanks again @andrewlock, I'll give this all a go. Really appreciate the help :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yeah, unfortunately, you're kinda screwed in that case 🙁
Basically, requiring concrete
IOptions<>
in theAddFoo()
method is not the recommended pattern, for exactly this reason! But if that's what it is, there's not a lot you can do...In the few cases I've run into this I have just manually bound the configuration instead. It's not ideal, and means you can't use the full options pattern, but it may do:
Rich Strahl has a nice post about this here: https://weblog.west-wind.com/posts/2017/dec/12/easy-configuration-binding-in-aspnet-core-revisited