Last active
November 1, 2018 14:30
-
-
Save NinoFloris/b59393193e47a0160c6f42eb6354683b to your computer and use it in GitHub Desktop.
OptionsFactory with func instead of new()
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
namespace Configuration | |
open System | |
open System.Runtime.CompilerServices | |
open Microsoft.Extensions.Options | |
open Microsoft.Extensions.DependencyInjection | |
open Microsoft.Extensions.Configuration | |
type OptionsFactoryFromFunc<'TOptions when 'TOptions : not struct and 'TOptions : (new : unit -> 'TOptions)> | |
(factoryFunc: Func<'TOptions>, | |
setups: IConfigureOptions<'TOptions> seq, | |
postConfigures: IPostConfigureOptions<'TOptions> seq) = | |
member __.Create(name) = | |
let options = factoryFunc.Invoke() | |
for setup in setups do | |
match setup with | |
| :? IConfigureNamedOptions<'TOptions> as namedSetup -> | |
namedSetup.Configure(name, options) | |
| _ -> | |
if name = Options.DefaultName then setup.Configure(options) | |
for post in postConfigures do | |
post.PostConfigure(name, options) | |
options | |
interface IOptionsFactory<'TOptions> with | |
member this.Create(name) = this.Create(name) | |
[<Extension>] | |
type FSharpOptionsExtensions() = | |
[<Extension>] | |
static member Configure<'TOptions when 'TOptions : not struct and 'TOptions : (new : unit -> 'TOptions)>(services: IServiceCollection, optionsFactory: Func<'TOptions>) = | |
if System.Object.ReferenceEquals(optionsFactory.Invoke(), optionsFactory.Invoke()) then | |
invalidArg "optionsFactory" "Options factory function is expected to return new instances on invocation, use OptionsWrapper for singletons." | |
let svc (ctx: IServiceProvider) : IOptionsFactory<'TOptions> = | |
upcast OptionsFactoryFromFunc<'TOptions>(optionsFactory, ctx.GetService<_>(), ctx.GetService<_>()) | |
services.AddSingleton<IOptionsFactory<'TOptions>>(svc) |
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
module Sample | |
open Configuration | |
open Microsoft.Extensions.Configuration | |
[<CLIMutable>] | |
type MyClientOptions = | |
{ | |
Host: string | |
} | |
let configureServices (services: IServiceCollection) (config: IConfigurationRoot) = | |
services.Configure<_>(fun () -> { Host = "127.0.0.1" }) | |
// Or whatever | |
services.Configure<_>(fun () -> | |
let host = defaultArg (Option.ofObj(config.GetValue<string>("MyClient:Host"))) "127.0.0.1" | |
{ Host = host } | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment