简体   繁体   中英

How to use IOptions pattern in Azure Function V3 using .NET Core

My requirement is to read values from local.settings.json using IOptions pattern

My localsettings.json:

{
  "IsEncrypted": false,
  "Values": {
    "MyOptions:MyCustomSetting": "Foobar",
    "MyOptions:DatabaseName": "Confirmed",
    "MyOptions:Schema": "User",
    "MyOptions:Role": "Dev",
    "MyOptions:UserName": "Avinash"
  }
}

My binding class looks like:

public class MyOptions
    {
        public string MyCustomSetting { get; set; }
        public string DatabaseName { get; set; }
        public string Schema { get; set; }
        public string Role { get; set; }
        public string UserName { get; set; }
    }

Startup.cs

[assembly: FunctionsStartup(typeof(FunctionApp2.Startup))]
namespace FunctionApp2
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddSingleton<IEmployee, Employee>();

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

My Consuming class:

    public class Employee: IEmployee
    {
        private readonly MyOptions _settings;

        public Employee(IOptions<MyOptions> options)
        {
            _settings = options.Value;
        }
    }

If and only if I write my properties prefix with MyOptions: in the local.settings.json then only its working fine so I'm able to read values from Employee class.

But I want to maintain my details in local.settings.json as:

{
  "MyOptions":{
    "MyCustomSetting": "Foobar",
    "DatabaseName": "Confirmed",
    "Schema": "User",
    "Role": "Dev",
    "UserName": "Manish"
   }
}

If I maintain my settings file like above then I'm unable to read values in my Employee class.

Could someone help me with this issue?

Well actually you can't and you shouldn't. Local.settings.json is not a classic json configuration file that you load in your configuration. It's a file containing settings that will be loaded by the azure function runtime as environment variables to mimic what happen on Azure with the Azure application settings. It's not the same as the appsetttings.json in an ASP.NET Core Web App. In local.settings.json the settings have the same format as environment variables or settings you would declare in Azure portal.

As far as I know there is no way for your to maintain your local.settings.json file in the format you want. Of course you could have another json file, "appsettings.json" for instance, and load it in configuration but I would not do that if I were you because you won't be able to put all your settings in there (settings present in bindings can't be put in there for instance).

I think once you get used to the format with : and that it would map to configuration sections like your json sections, it's fine to use the local.settings.json file like that.

You can use the local.settings.json in the below format for your code to work

 { "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "dotnet" }, "MyOptions"{ "MyCustomSetting": "Foobar", "DatabaseName": "Confirmed", "Schema": "User", "Role": "Dev", "UserName": "Manish" } }

When you add these in azure portal settings, then you need to prefix them - "MyOptions:MyCustomSetting": "Foobar"

I have implemented it in the latest func app version. Revert to me if you face any issue

I Can suggest, as a best practice, to wrap all related app settings code like:

{
    "ConnectionStrings": {
    },
    "AppSettings": {
        "MyOptions": {
            ...
        }
    },
}

public class AppSettingsConfig 
{
    public MyOptions MyOptions { get; set;}
}

After registering the AppSettings with, you can get the sub-section by its name, then bind it simply to your class MyOptions :

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
    this._appSettingsconfigurationSection = Configuration.GetSection("AppSettings");
    services.Configure<AppSettingsConfig>(this._appSettingsconfigurationSection);

    IConfigurationSection myOptionsSection = this._appSettingsconfigurationSection.GetSection("MyOptions");
    MyOptions myOptions = new MyOptions();
    myOptionsSection.Bind(myOptions);
}

I missed settings related to local.settings.json in my azure function.csproj

You can use a new appsettings.json file and inject it using Configuration builder if you use App Service plan.

If you are using consumption plan or premium plan, it will throw errors intermittently as the configuration file is not available at startup when the app starts to scale.

One way to use json file is to do it at function level. You can build a static class with static method which can be reused in all classes.

private static IConfigurationRoot GetConfig(ExecutionContext context)
        {
            return new ConfigurationBuilder()
                        .SetBasePath(context.FunctionAppDirectory)
                        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                        .AddEnvironmentVariables()
                        .Build();
        }

And call it in your trigger


        [FunctionName("myhttptrigger")]
        public async Task<IActionResult> MyHttpTrigger(
            [HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req, ExecutionContext context){
   var config = getConfig(context);
   // use you 


}

You can even build more advanced methods to get a typed config class and call it in your functions


public static MyOptions GetMyOptions(ExecutionContext executionContext){
    var config = GetConfig(executionContext);
    return config.GetSection("MyOptions").GetValue<MyOptions>();

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM