Le nouveau SDK Azure Function 3.0 fournit un moyen d'implémenter une classe de démarrage. Il donne accès à la collection de services disponibles par injection de dépendances, où je peux ajouter mes propres composants et services tiers.
Mais je ne sais pas comment utiliser un fichier de configuration.
[Assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
namespace MyNamespace
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
...
Mes services tiers prennent de grandes structures comme paramètre, et ces fichiers de configuration sont copiés avec des binaires. Je peux les copier dans une sous-section d'un fichier appsettings.json:
{
"MachineLearningConfig" : {
( about 50+ parameters and subsections )
}
}
Les valeurs de configuration sont mises à jour en fonction de l'environnement de déploiement. J'utilise la tâche de transformation de fichier d'Azure Devops pour cela: les valeurs de production sont différentes des valeurs de préparation et de développement.
Compte tenu de la documentation https://docs.Microsoft.com/en-us/Azure/azure-functions/functions-dotnet-dependency-injection la façon de charger ces options est:
builder.Services.AddOptions<MachineLearningConfig>()
.Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("MachineLearningConfig").Bind(settings);
});
Mais cela nécessite d'ajouter tous les paramètres en tant que chaînes clé/valeur dans l'environnement de l'hôte, et c'est ce que je ne veux pas faire. Il y en a trop et ce n'est pas aussi facile à maintenir que dans un fichier de configuration json.
J'ai copié ça appsettings.json aux côtés de Host.json.
Mais le fichier appsettings.json lu au démarrage par le SDK Azure Function n'est pas appsettings.json de mon application mais appsettings.json des outils Azure Function. Donc configuration.GetSection("MachineLearningConfig")
renvoie des valeurs vides car il n'y a pas de fichier appsettings.json dans le dossier bin des outils Azure Function.
Donc, ma question: comment faire lire ma section MachineLearningConfig
à partir de mon fichier appsetting.json
Injecté comme IOption<MachineLearningConfig>
Dans mon application?
Dans la classe de démarrage:
IConfigurationRoot config = new ConfigurationBuilder()
.SetBasePath(Environment.CurrentDirectory)
.AddJsonFile("someSettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
Ajoutez un fichier json à votre projet contenant les paramètres. Notez que local.settings.json est ignoré/supprimé lors du déploiement. (Nommez le fichier autrement.)
Après quelques recherches, je suis tombé sur ce fil sur Githib
en utilisant appsettings.json + IConfiguration dans Function App
À partir de laquelle j'ai créé l'extension suivante en me basant sur les commentaires et suggestions qui ont fonctionné.
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;
}
}
L'idée principale est d'extraire tous les types de configuration actuellement enregistrés, de créer un nouveau générateur, d'appliquer une configuration personnalisée et de créer une nouvelle configuration avec les détails de configuration d'origine et personnalisés fusionnés en un seul.
Il serait alors utilisé dans 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);
});
}
}
Ce qui précède devrait maintenant pouvoir obtenir les paramètres de votre configuration personnalisée.