19

How to get access to the ExecutionContext.FunctionAppDirectory in Functions Startup class so I can setup my Configuration correct. Please see the following Startup code:

[assembly: WebJobsStartup(typeof(FuncStartup))]
namespace Function.Test
{
    public class FuncStartup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder builder)
        {
            var config = new ConfigurationBuilder()
               .SetBasePath(“”/* How to get the Context here. I cann’t DI it 
                           as it requires default constructor*/)
               .AddJsonFile(“local.settings.json”, true, reloadOnChange: true)
               .AddEnvironmentVariables()
               .Build();

        }
    }
 }
Alex AIT
  • 17,361
  • 3
  • 36
  • 73
Soma Yarlagadda
  • 2,875
  • 3
  • 15
  • 37

3 Answers3

24

You don't have the ExecutionContext since your Azure Function is not yet processing an actual function call. But you don't need it either - the local.settings.json is automatically parsed into the environment variables.

If you really need the directory, you can use %HOME%/site/wwwroot in Azure, and AzureWebJobsScriptRoot when running locally. This is the equivalent of FunctionAppDirectory.

This is also a good discussion about this topic.

    public void Configure(IWebJobsBuilder builder)
    {
        var local_root = Environment.GetEnvironmentVariable("AzureWebJobsScriptRoot");
        var azure_root = $"{Environment.GetEnvironmentVariable("HOME")}/site/wwwroot";

        var actual_root = local_root ?? azure_root;

        var config = new Microsoft.Extensions.Configuration.ConfigurationBuilder()
            .SetBasePath(actual_root)
            .AddJsonFile("SomeOther.json")
            .AddEnvironmentVariables()
            .Build();

        var appInsightsSetting = config.GetSection("APPINSIGHTS_INSTRUMENTATIONKEY");
        string val = appInsightsSetting.Value;
        var helloSetting = config.GetSection("hello");
        string val = helloSetting.Value;

        //...
    }

Example local.settings.json:

{
  "IsEncrypted": false,
  "Values": {
    "APPINSIGHTS_INSTRUMENTATIONKEY": "123456..."
  }
}

Example SomeOther.json

{
  "hello":  "world"
}
Alex AIT
  • 17,361
  • 3
  • 36
  • 73
  • But, local.settings.json is only for development environment what if I want to use a JSON file for settings in Azure or a separate file like appsettings.json? This is especially a problem when running the function inside docker. – Soma Yarlagadda Apr 10 '19 at 18:19
  • I have updated my answer - be careful about putting certain settings like secrets in docker images though - see https://medium.com/@mccode/dont-embed-configuration-or-secrets-in-docker-images-7b2e0f916fdd – Alex AIT Apr 10 '19 at 18:49
  • All the secrets are fed to the service through Vault so none of them are added to the image. Let me try the solution, as far as I know the Directory.GetCUrrentDirectory() won't work. Thank you – Soma Yarlagadda Apr 10 '19 at 18:52
  • Actually, my code does not work in Azure... https://github.com/MicrosoftDocs/azure-docs/issues/26761 now i am curious ;-) Will update the answer again in a couple of minutes.. – Alex AIT Apr 10 '19 at 18:58
12

Use below code ,It worked for me.

var executioncontextoptions = builder.Services.BuildServiceProvider()
         .GetService<IOptions<ExecutionContextOptions>>().Value;

var currentDirectory = executioncontextoptions.AppDirectory;

configuration = configurationBuilder.SetBasePath(currentDirectory)
          .AddJsonFile(ConfigFile, optional: false, reloadOnChange: true)    
          .Build();
slfan
  • 8,950
  • 115
  • 65
  • 78
Vamshi CH
  • 121
  • 1
  • 4
0

When the documentation says In a function app, the default is %HOME%\site\wwwroot it means that if you do not specify this environment variable, the functions host will use %HOME%\site\wwwroot.

public void Configure(IWebJobsBuilder builder)
    {
        var localRoot = Environment.GetEnvironmentVariable("AzureWebJobsScriptRoot");
        var azureRoot = $@"{Environment.GetEnvironmentVariable("HOME")}\site\wwwroot";

        var config = new Microsoft.Extensions.Configuration.ConfigurationBuilder()
            .SetBasePath(localRoot ?? azureRoot )
            .AddJsonFile("appsettings.json", true)
            .AddJsonFile("local.settings.json", true)
            .AddEnvironmentVariables()
            .Build();            
    }