Получить корневой каталог приложения-функции Azure v2
Я создаю приложение-функцию Azure (v2). Задачи конфигурации, необходимые для всех функций, выполняются в классе Setup, который структурирован следующим образом:
[assembly: WebJobsStartup(typeof(Startup))]
internal class Startup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
Configuration = new ConfigurationBuilder()
.SetBasePath(<functionAppDirectory>)
.AddJsonFile("local.settings.json")
.Build();
builder.AddDependencyInjection(ConfigureServices);
}
public IConfiguration Configuration { get; set; }
private void ConfigureServices(IServiceCollection services)
{
var connection = Configuration.GetConnectionString("<myconnection-string>");
...
}
}
В ConfigureServices
я хочу прочитать строку подключения из файла конфигурации. Для этого была указана базовая папка приложения функции с помощью SetBasePath
. Но я не нашел способа получить доступ к этому пути. Согласно https://github.com/Azure/azure-functions-host/wiki/Retrieving-information-about-the-currently-running-function, ExecutionContext
может быть введен в функцию, которая содержит путь. Но как мне получить доступ к ExecutionContext
в моем классе Startup
?
Ответы
Ответ 1
TL; DR: просто используйте Environment.GetEnvironmentVariable.
Подход ConfigurationBuilder обнаруживается во многих постах блога и работал до тех пор, пока мы не начали делать DI. Но здесь нет параметра контекста, поэтому ConfigurationBuilder сразу начинает вызывать некоторое напряжение.
Я думаю, что люди пошли в этом направлении, потому что в Azure Functions 2 мы переключились на конфигурацию ядра ASP.NET, из-за чего ConfigurationManager перестал работать. Конфигурация Builder была разумным местом для посадки. Он был схож с MVC и работал до появления DI.
Но теперь, когда мы выполняем DI, стало ясно, что Environment.GetEnvironmentVariable, возможно, был лучшим выбором для этой платформы... Там меньше накладных расходов кода, и он четко отображается в модели конфигурации функций Azure: в dev, это подбирает элементы в массиве local.settings.json> Values, а в производственном процессе он выбирает переменные вашей среды, и он просто работает.
Это отличается от того, что мы делаем в MVC. Однако до тех пор, пока эти платформы не станут ближе к паритету, мы должны делать то, что имеет смысл в функциях, а не пытаться навязывать решения из MVC.
Итак:
[assembly: WebJobsStartup(typeof(StartUp))]
namespace Keystone.AzureFunctions
{
public class StartUp : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
var connectionString = Environment.GetEnvironmentVariable("KeystoneDB");
// Configure EF
builder.Services.AddDbContext<KeystoneDB>(options => options.UseSqlServer(connectionString));
}
}
}
И ваш local.settings.json может выглядеть так:
{
"IsEncrypted": false,
"Values": {
"KeystoneDB": "[CONNECTION STRING HERE]"
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}
Вы также можете использовать Key Vault с Environment. Это прекрасно работает.
Ответ 2
Единственный обходной путь, который я нашел для компоновщика конфигурации в методе Startup(), - это использовать жестко закодированный путь "/home/site/wwwroot/"
var config = new ConfigurationBuilder()
.SetBasePath("/home/site/wwwroot/")
.AddJsonFile("config.json", optional: false)
.Build();
System.Environment.CurrentDirectory не работает в Azure. Хотя это работает локально. Но в Azure выдает ошибку: файл конфигурации 'config.json' не найден и не является обязательным. Физический путь - "/config.json". И функция не запускается.
Ответ 3
Где вы пытаетесь использовать эту строку подключения? Я уже отвечал на похожий (но не точный) вопрос ранее здесь - это поможет вам получить то, что вам нужно? https://github.com/Azure/azure-webjobs-sdk/issues/1817#issuecomment-418430676
Ответ 4
Приветствие,
Я нашел решение, которое работает в автозагрузке:
var fileInfo = new FileInfo(Assembly.GetExecutingAssembly().Location);
string path = fileInfo.Directory.Parent.FullName;
var configuration = new ConfigurationBuilder()
.SetBasePath(Environment.CurrentDirectory)
.SetBasePath(path)
.AddJsonFile("appsettings.json", false)
.Build();
Ответ 5
Вы можете использовать этот кусок кода в вашем файле запуска.
Я только что проверил его сегодня для своего проекта, и он работает как на облачном, так и на локальном уровне.
var executioncontextoptions = builder.Services.BuildServiceProvider()
.GetService<IOptions<ExecutionContextOptions>>().Value;
var currentDirectory = executioncontextoptions.AppDirectory;
Ответ 6
Попробуйте использовать Environment.CurrentDirectory