Azure / azure-functions-dotnet-worker

Azure Functions out-of-process .NET language worker
MIT License
416 stars 181 forks source link

Configuration in isolated mode #2207

Open phatcher opened 8 months ago

phatcher commented 8 months ago

I'm trying to change my .NET 6 Azure Functions V4 project to isolated mode but seem to be missing some stuff

  1. How to get the ApplicationRootPath or Environment values in either ConfigureHostConfiguration/ConfigureAppConfiguration
  2. How to get the IConfiguration in ConfigureServices

Previously I could use the IFunctionConfigurationBuilder/IFunctionsHostBuiler GetContext() method but I can't find an equivalent

davidpetric commented 8 months ago

Hi @phatcher,

  1. ConfigureAppConfiguration has an overload which takes an Action of type: Action<HostBuilderContext, IConfigurationBuilder> configureDelegate)
    • I think ApplicationRootPath now is accessible from the HostBuilderContext type and now has the name ContentRootPath,
    • You can access the Environment values by using the static class Environment or if you need something which was not declared there you can use string myCustomEnvVariable = Environment.GetEnvironmentVariable("my_custom_env_variable ")

Example for ConfigureAppConfiguration

    .ConfigureAppConfiguration((hostBuilderContext, builder) =>
    {
        IHostEnvironment hostingEnvironment = hostBuilderContext.HostingEnvironment;
        string contentRootPath = hostingEnvironment.ContentRootPath;

        IConfiguration configuration = hostBuilderContext.Configuration;

        string myCustomEnvVariable = Environment.GetEnvironmentVariable("my_custom_env_variable");

        // Example of configuring
        // local.settings.json, environment variables, visual studio user secrets.
        builder.SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables()
                .AddUserSecrets(Assembly.GetExecutingAssembly(), optional: true);
    })
  1. To get IConfiguration in ConfigureServices you need to use ConfigureServices(Action<HostBuilderContext, IServiceCollection> configureDelegate); overload.

Example:

    .ConfigureServices((hostBuilderContext, services) =>
    {
        IConfiguration configuration = hostBuilderContext.Configuration;
        string sqlConnectionString = configuration.GetValue<string>("SqlConnectionString");

        services.AddScoped<IUserService, UserService>();
    })
phatcher commented 8 months ago

@davidpetric Thanks for that, it's unblocked me from proceeding - I think something along these lines needs to go into the migration guide as finding the overloads is a bit non-obvious.

Just need to see if it works now and whether I can easily get over the lack of INameResolver ;-)

satvu commented 6 months ago

Flagging this as an opportunity to improve samples/docs.

pregress commented 6 months ago

The answer in this issue is indeed the correct one, using Directory.GetCurrentDirectroy() to set the configurationbuilder base path.

The documentation here is out of date, not relevant for isolated workers: https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#customizing-configuration-sources

Best to also add the sample there:

https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureAppConfiguration((context, configBuilder) =>
    {
        configBuilder
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: false);
    })

If you use the docs, this results in:

Unhandled exception. System.IO.FileNotFoundException: The configuration file 'appsettings.Staging.json' was not found and is not optional. The expected physical path was '/azure-functions-host/appsettings.Staging.json'.

ac931274 commented 3 weeks ago

Re getting over the lack of INameResolver, take a look at my post on Stack Overflow about how I resolved my issue. https://stackoverflow.com/questions/78897966/azure-functions-trigger-variables-isolated-functions/78897967