Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Функции Azure поддерживают шаблон проектирования программного обеспечения для внедрения зависимостей (DI), который является методом для достижения инверсии элемента управления (IoC) между классами и их зависимостями.
Внедрение зависимостей в Функции Azure основано на функциях внедрения зависимостей .NET Core. Рекомендуется ознакомиться с внедрением зависимостей .NET Core . Существуют различия в переопределении зависимостей и в способах чтения значений конфигурации в тарифе Consumption с помощью функций Azure.
Поддержка внедрения зависимостей начинается с Функций Azure 2.x.
Шаблоны внедрения зависимостей различаются в зависимости от того, выполняются ли функции C# в процессе или вне процесса.
Это важно
Руководство в этой статье относится только к функциям библиотеки классов C#, которые выполняются в процессе с средой выполнения. Эта пользовательская модель внедрения зависимостей не применяется к изолированным функциям .NET, что позволяет запускать функции .NET вне процесса. Модель изолированного рабочего процесса .NET зависит от стандартных моделей внедрения зависимостей ASP.NET Core. Дополнительные сведения см. в руководстве по внедрению зависимостей в руководстве по изолированному рабочему процессу .NET.
Предпосылки
Прежде чем использовать внедрение зависимостей, необходимо установить следующие пакеты NuGet:
Пакет Microsoft.NET.Sdk.Functions версии 1.0.28 или более поздней версии
Microsoft.Extensions.DependencyInjection (в настоящее время поддерживается только версия 2.x или более поздней версии)
Регистрация услуг
Чтобы зарегистрировать службы, создайте метод, который настроит и добавит компоненты в экземпляр IFunctionsHostBuilder
. Хост Azure Functions создает экземпляр IFunctionsHostBuilder
и передает его непосредственно в ваш метод.
Предупреждение
Для приложений-функций, работающих в планах "Потребление" или "Премиум", изменения значений конфигурации, используемых в триггерах, могут привести к ошибкам масштабирования. Любые изменения этих свойств класса FunctionsStartup
приводят к ошибке запуска приложения-функции.
Внедрение IConfiguration
может привести к неожиданному поведению. Дополнительные сведения о добавлении источников конфигурации см. в разделе "Настройка источников конфигурации".
Чтобы зарегистрировать метод, добавьте FunctionsStartup
атрибут сборки, указывающий имя типа, используемое во время запуска.
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
namespace MyNamespace;
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
builder.Services.AddSingleton<IMyService>((s) => {
return new MyService();
});
builder.Services.AddSingleton<ILoggerProvider, MyLoggerProvider>();
}
}
В этом примере используется пакет Microsoft.Extensions.Http, необходимый для регистрации компонента при запуске.
Предупреждения
Ряд шагов регистрации, выполняемых до и после выполнения, обрабатывает класс запуска. Поэтому помните о следующих элементах:
Класс запуска предназначен только для настройки и регистрации. Избегайте использования служб, зарегистрированных при запуске во время запуска. Например, не пытайтесь записать сообщение в средство ведения журнала, зарегистрированное во время запуска. Эта точка процесса регистрации слишком ранняя, чтобы службы были доступны для использования.
Configure
После запуска метода среда выполнения Функций продолжает регистрировать другие зависимости, которые могут повлиять на работу служб.Контейнер внедрения зависимостей содержит только явно зарегистрированные типы. Единственными службами, доступными как внедренные типы, являются те, которые настроены в методе
Configure
. В результате типы, относящиеся к функциям, такие какBindingContext
иExecutionContext
недоступны во время установки или в качестве внедренных типов.Настройка проверки подлинности ASP.NET не поддерживается. Узел функций настраивает службы проверки подлинности ASP.NET для правильного предоставления API для основных операций жизненного цикла. Другие конфигурации в пользовательском
Startup
классе могут переопределить эту конфигурацию, что приводит к непредвиденным последствиям. Например, вызовbuilder.Services.AddAuthentication()
может нарушить проверку подлинности между порталом и узлом, что ведет к сообщениям, таким как среда выполнения Функций Azure недоступна.
Использование внедренных зависимостей
Внедрение конструктора используется для того, чтобы сделать зависимости доступными в функции. Использование внедрения конструктора требует, чтобы статические классы не использовались для внедренных служб или для классов функций.
Следующий пример демонстрирует, как зависимости IMyService
и HttpClient
внедряются в функцию, инициируемую HTTP-запросом.
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using System.Net.Http;
using System.Threading.Tasks;
namespace MyNamespace;
public class MyHttpTrigger
{
private readonly HttpClient _client;
private readonly IMyService _service;
public MyHttpTrigger(IHttpClientFactory httpClientFactory, IMyService service)
{
this._client = httpClientFactory.CreateClient();
this._service = service;
}
[FunctionName("MyHttpTrigger")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
var response = await _client.GetAsync("https://microsoft.com");
var message = _service.GetMessage();
return new OkObjectResult("Response from function with injected dependencies.");
}
}
В этом примере используется пакет Microsoft.Extensions.Http, необходимый для регистрации компонента при запуске.
Срок службы
Приложения Azure Functions предоставляют те же сроки жизни служб, что и внедрение зависимостей в ASP.NET. Для приложения Functions, различные временные циклы служб ведут себя следующим образом:
- Временные: временные сервисы создаются при каждом разрешении сервиса.
- Ограниченная область: Время существования службы с ограниченной областью соответствует времени выполнения функции. Службы с областью действия создаются один раз для каждого выполнения функции. Последующие запросы для данной службы в процессе выполнения повторно используют существующий экземпляр службы.
-
Singleton: время существования службы singleton соответствует времени существования узла и повторно используется во время выполнения функций в этом экземпляре. Службы с временем существования Singleton рекомендуются для подключений и клиентов, например, экземпляров
DocumentClient
илиHttpClient
.
Просмотрите или скачайте пример различных времен существования службы на GitHub.
Службы ведения журнала
Если вам нужен собственный поставщик ведения журнала, зарегистрируйте настраиваемый тип в качестве экземпляра ILoggerProvider
, который доступен через пакет NuGet Microsoft.Extensions.Logging.Abstractions .
Application Insights автоматически добавляется функциями Azure.
Предупреждение
- Не добавляйте
AddApplicationInsightsTelemetry()
в коллекцию служб, регистрирующую службы, которые конфликтуют со службами, предоставляемыми средой. - Не регистрируйте собственные
TelemetryConfiguration
илиTelemetryClient
если вы используете встроенные функции Application Insights. Если вам необходимо настроить собственныйTelemetryClient
экземпляр, создайте его с помощью внедренногоTelemetryConfiguration
, как показано в документе "Регистрация пользовательской телеметрии в функциях C#".
ILogger<T> и ILoggerFactory
Хост внедряет службы ILogger<T>
и ILoggerFactory
в конструкторы. Однако по умолчанию эти новые фильтры ведения журнала фильтруются из журналов функций. Необходимо изменить host.json
файл, чтобы выбрать дополнительные фильтры и категории.
В следующем примере показано, как добавить ILogger<HttpTrigger>
с журналами, которые открыты для узла.
namespace MyNamespace;
public class HttpTrigger
{
private readonly ILogger<HttpTrigger> _log;
public HttpTrigger(ILogger<HttpTrigger> log)
{
_log = log;
}
[FunctionName("HttpTrigger")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req)
{
_log.LogInformation("C# HTTP trigger function processed a request.");
// ...
}
В следующем примере host.json
файла добавляется фильтр журнала.
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
},
"logLevel": {
"MyNamespace.HttpTrigger": "Information"
}
}
}
Дополнительные сведения об уровнях журналов см. в разделе "Настройка уровней журнала".
Сервисы приложения Function app
Хост функции регистрирует множество служб. Следующие службы безопасно использовать в качестве зависимостей в приложении:
Тип службы | Продолжительность жизни | Описание |
---|---|---|
Microsoft.Extensions.Configuration.IConfiguration |
Синглтон | Конфигурация среды выполнения |
Microsoft.Azure.WebJobs.Host.Executors.IHostIdProvider |
Синглтон | Ответственность за предоставление идентификатора экземпляра узла |
Если существуют другие службы, от которых требуется взять зависимость, создайте проблему и предложите их на сайте GitHub.
Переопределение служб хоста
Переопределение служб, предоставляемых узлом, в настоящее время не поддерживается. Если вы хотите переопределить службы, создайте проблему и предложите их на сайте GitHub.
Работа с параметрами и настройками
Значения, определенные в параметрах приложения , доступны в экземпляре IConfiguration
, что позволяет считывать значения параметров приложения в классе запуска.
Вы можете извлечь значения из экземпляра IConfiguration
в пользовательский тип. Копирование значений параметров приложения в пользовательский тип упрощает тестирование служб путем внедрения этих значений. Параметры, прочитанные в экземпляре конфигурации, должны быть простыми парами "ключ-значение". Для функций, выполняемых в плане Elastic Premium, имена параметров приложения могут содержать только буквы, цифры (), точки (0-9
.
), двоеточия (:
) и символы подчеркивания (_
). Дополнительные сведения см. в рекомендациях по настройке приложений.
Рассмотрим следующий класс, включающий свойство с именем, согласованное с параметром приложения:
public class MyOptions
{
public string MyCustomSetting { get; set; }
}
И файл, который может структурировать настраиваемый local.settings.json
параметр следующим образом:
{
"IsEncrypted": false,
"Values": {
"MyOptions:MyCustomSetting": "Foobar"
}
}
Из метода Startup.Configure
можно извлечь значения из экземпляра IConfiguration
в пользовательский тип с помощью следующего кода:
builder.Services.AddOptions<MyOptions>()
.Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("MyOptions").Bind(settings);
});
Вызов Bind
копирует значения с соответствующими именами свойств из конфигурации в пользовательский экземпляр. Экземпляр параметров теперь доступен в контейнере IoC для внедрения в функцию.
Объект options внедряется в функцию в качестве экземпляра универсального IOptions
интерфейса.
Value
Используйте свойство для доступа к значениям, найденным в конфигурации.
using System;
using Microsoft.Extensions.Options;
public class HttpTrigger
{
private readonly MyOptions _settings;
public HttpTrigger(IOptions<MyOptions> options)
{
_settings = options.Value;
}
}
Дополнительные сведения см. в разделе "Шаблон параметров в ASP.NET Core".
Использование секретов пользователей ASP.NET Core
При локальной разработке приложения ASP.NET Core предоставляет средство диспетчера секретов , позволяющее хранить секретную информацию за пределами корневого каталога проекта. Это делает менее вероятным, что секреты случайно фиксируются в системе управления версиями. Azure Functions Core Tools (версия 3.0.3233 или более поздней версии) автоматически считывает секреты, созданные ASP.NET Core Secret Manager.
Чтобы настроить проект Функций Azure .NET для использования секретов пользователей, выполните следующую команду в корневом каталоге проекта.
dotnet user-secrets init
Затем используйте dotnet user-secrets set
команду для создания или обновления секретов.
dotnet user-secrets set MySecret "my secret value"
Чтобы получить доступ к значениям секретов пользователей в коде приложения-функции, используйте IConfiguration
или IOptions
.
Настройка источников конфигурации
Чтобы указать другие источники конфигурации, необходимо переопределить метод ConfigureAppConfiguration
в классе вашего приложения с функцией StartUp
.
Следующий пример добавляет значения конфигурации как из базовых, так и необязательных файлов параметров приложения для конкретной среды.
using System.IO;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
namespace MyNamespace;
public class Startup : FunctionsStartup
{
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
{
FunctionsHostBuilderContext context = builder.GetContext();
builder.ConfigurationBuilder
.AddJsonFile(Path.Combine(context.ApplicationRootPath, "appsettings.json"), optional: true, reloadOnChange: false)
.AddJsonFile(Path.Combine(context.ApplicationRootPath, $"appsettings.{context.EnvironmentName}.json"), optional: true, reloadOnChange: false)
.AddEnvironmentVariables();
}
public override void Configure(IFunctionsHostBuilder builder)
{
}
}
Добавьте поставщиков конфигурации в ConfigurationBuilder
свойство IFunctionsConfigurationBuilder
. Дополнительные сведения об использовании поставщиков конфигураций см. в разделе "Конфигурация" в ASP.NET Core.
A FunctionsHostBuilderContext
получается из IFunctionsConfigurationBuilder.GetContext()
. Используйте этот контекст для получения текущего имени среды и разрешения расположения файлов конфигурации в папке приложения-функции.
По умолчанию файлы конфигурации, такие как appsettings.json
не копируются автоматически в выходную папку приложения-функции. Обновите .csproj
файл, чтобы он соответствовал следующему образцу, чтобы убедиться, что файлы копируются.
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
Дальнейшие шаги
Дополнительные сведения см. в следующих ресурсах: