web-dev-qa-db-ja.com

Azure Function 3.0構成にappsettings.jsonファイルを追加するにはどうすればよいですか?

新しいAzure Function 3.0 SDKは、スタートアップクラスを実装する方法を提供します。依存性注入によって利用可能なサービスのコレクションへのアクセスを提供し、独自のコンポーネントやサードパーティのサービスを追加できます。

しかし、設定ファイルの使い方がわかりません。

_[Assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
namespace MyNamespace
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
...
_

私のサードパーティのサービスは大きな構造をパラメーターとして取り、それらの構成ファイルはバイナリと共にコピーされます。 appsettings.jsonファイルのサブセクションにそれらをコピーできます:

_{
  "MachineLearningConfig" : {
     ( about 50+ parameters and subsections )
  }
}
_

構成の値は、デプロイメントの環境に応じて更新されます。そのために、Azure Devopsのファイル変換タスクを使用します。本番値は、ステージング値や開発値とは異なります。

ドキュメント https://docs.Microsoft.com/en-us/Azure/azure-functions/functions-dotnet-dependency-injection これらのオプションを読み込む方法は次のとおりです:

_builder.Services.AddOptions<MachineLearningConfig>()
                .Configure<IConfiguration>((settings, configuration) =>
                                           {
                                                configuration.GetSection("MachineLearningConfig").Bind(settings);
                                           });
_

しかし、それにはホストの環境ですべての設定をキー/値stringsとして追加する必要があり、それは私がしたくないことです。それらが多すぎて、json設定ファイルのように維持するのは簡単ではありません。

Host.jsonと一緒にappsettings.jsonをコピーしました。

ただし、Azure Function SDKによって起動時に読み取られるappsettings.jsonファイルは、アプリケーションのappsettings.jsonではなく、Azure Functionツールのappsettings.jsonです。したがって、Azure Function tools binフォルダーにappsettings.jsonファイルがないため、configuration.GetSection("MachineLearningConfig")は空の値を返します。

だから、私の質問:MachineLearningConfigセクションを私の_appsetting.json_ファイルから読み取って、アプリで_IOption<MachineLearningConfig>_として挿入するにはどうすればよいですか?

3

スタートアップクラス:

    IConfigurationRoot config = new ConfigurationBuilder()
              .SetBasePath(Environment.CurrentDirectory)
              .AddJsonFile("someSettings.json", optional: true, reloadOnChange: true)
              .AddEnvironmentVariables()
              .Build();

設定を保持するプロジェクトにjsonファイルを追加します。 local.settings.jsonは、デプロイメント中に無視/削除されることに注意してください。 (ファイルに別の名前を付けます。)

2
Zsolt Bendes

いくつかの調査の後、私はGithibでこのスレッドに出くわしました

appsettings.json + IConfigurationをFunction Appで使用

そこから、機能したことが示されたコメントと提案に基づいて、次の拡張機能を作成しました。

public static class FunctionHostBuilderExtensions {
    /// <summary>
    /// Set up the configuration for the builder itself. This replaces the 
    /// currently registered configuration with additional custom configuration.
    /// This can be called multiple times and the results will be additive.
    /// </summary>
    public static IFunctionsHostBuilder ConfigureHostConfiguration (
        this IFunctionsHostBuilder builder, 
        Action<IServiceProvider, IConfigurationBuilder> configureDelegate) {
        IServiceCollection services = builder.Services;            
        var providers = new List<IConfigurationProvider>();            
        //Cache all current configuration provider
        foreach (var descriptor in services.Where(d => d.ServiceType == typeof(IConfiguration)).ToList()) {
            var existingConfiguration = descriptor.ImplementationInstance as IConfigurationRoot;
            if (existingConfiguration is null) {
                continue;
            }
            providers.AddRange(existingConfiguration.Providers);
            services.Remove(descriptor);
        }
        //add new configuration based on original and newly added configuration
        services.AddSingleton<IConfiguration>(sp => {
            var configurationBuilder = new ConfigurationBuilder();                    
            //call custom configuration
            configureDelegate?.Invoke(sp, configurationBuilder);                
            providers.AddRange(configurationBuilder.Build().Providers);                
            return new ConfigurationRoot(providers);
        });            
        return builder;
    }
}

主なアイデアは、現在登録されているすべての構成関連タイプを抽出し、新しいビルダーを作成し、カスタム構成を適用し、元の構成とカスタム構成の詳細を1つにマージして新しい構成を構築することです。

次に、Startupで使用されます

public class Startup : FunctionsStartup {
    public override void Configure(IFunctionsHostBuilder builder) {
        builder.ConfigureHostConfiguration((sp, config) => {
            var executioncontextoptions = sp.GetService<IOptions<ExecutionContextOptions>>().Value;
            var currentDirectory = executioncontextoptions.AppDirectory;

            config
                .SetBasePath(currentDirectory)
                .AddJsonFile("appSettings.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables();

            //if there are multiple settings files, consider extracting the list,
            //enumerating it and adding them to the configuration builder.
        });

        builder.Services
            .AddOptions<MachineLearningConfig>()
            .Configure<IConfiguration>((settings, configuration) => {
                configuration.GetSection("MachineLearningConfig").Bind(settings);
            });
    }
}

これで、カスタム構成から設定を取得できるようになります。

1
Nkosi