新しい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>
_として挿入するにはどうすればよいですか?
スタートアップクラス:
IConfigurationRoot config = new ConfigurationBuilder()
.SetBasePath(Environment.CurrentDirectory)
.AddJsonFile("someSettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
設定を保持するプロジェクトにjsonファイルを追加します。 local.settings.jsonは、デプロイメント中に無視/削除されることに注意してください。 (ファイルに別の名前を付けます。)
いくつかの調査の後、私は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);
});
}
}
これで、カスタム構成から設定を取得できるようになります。