Read and use settings from appsettings.json without IOptions?

后端 未结 2 1081
攒了一身酷
攒了一身酷 2020-12-11 20:40

.NET Core allows to lazily read settings from configuration file, de-serialize it to a POCO and register that POCO in built-in DI container with one line of code:

         


        
2条回答
  •  暖寄归人
    2020-12-11 21:41

    Deserialize options with configuration.Get or configuration.Bind call and register a POCO in DI container explicitly as singleton:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingletonFromFile(Configuration.GetSection("MySection"));
    }
    
    //...
    
    public static IServiceCollection AddSingletonFromFile(
        this IServiceCollection services,
        IConfiguration configuration)
        where TOptions : class, new()
    {
        //POCO is created with actual values 
        TOptions options = configuration.Get();
    
        services.AddSingleton(options);
    
        return services;
    }
    

    UPD: thanks to @NPNelson for .Get() hint.

    Then IOptions resolving is no longer needed, and the class dependencies become clear:

    public HomeController(MyOptions options)
    {
        _options = options;
    }
    

    FYI: reading from an external service (database etc.) is also possible this way:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransientFromService(reader => reader.GetOptions());
    }
    
    //...
    
    public static void AddTransientFromService(
        this IServiceCollection services,
        Func getOptions)
        where TReader : class
        where TOptions : class
    
    {
        services.AddTransient(provider => getOptions(provider.GetService()));
    }
    

    Remarks:

    • Singleton is not lazy (it's always instantiated at startup);
    • In case of singleton registration, any ability to update options at runtime is lost (.NET Core natively supports runtime file reloading with reloadOnChange option setup: .AddJsonFile("appsettings.json", false, reloadOnChange: true));

    If you really need the file reload and you still don't want to use IOptions, consider a transient resolving. Of course, per-request resolving can lead to the significant perfomance decrease.

提交回复
热议问题