Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O Azure Functions dá suporte ao padrão de design de software de injeção de dependência (DI), que é uma técnica para obter Inversão de Controle (IoC) entre classes e suas dependências.
A injeção de dependência no Azure Functions é baseada nos recursos de injeção de dependência do .NET Core. Recomenda-se familiaridade com injeção de dependência do .NET Core. Há diferenças na forma como você substitui dependências e como os valores de configuração são lidos com o Azure Functions no plano de Consumo.
O suporte para injeção de dependência começa com o Azure Functions 2.x.
Os padrões de injeção de dependência diferem dependendo se suas funções C# são executadas em processo ou fora do processo.
Importante
A orientação neste artigo se aplica somente às funções da biblioteca de classes C#, que são executadas em processo com o tempo de execução. Esse modelo de injeção de dependência personalizado não se aplica a funções isoladas do .NET, o que permite executar funções do .NET fora do processo. O modelo de processo de trabalho isolado do .NET depende de padrões regulares de injeção de dependência do ASP.NET Core. Para saber mais, consulte Injeção de dependência no guia do processo de trabalho isolado do .NET.
Pré-requisitos
Antes de poder usar a injeção de dependência, você deve instalar os seguintes pacotes NuGet:
Microsoft.NET.Sdk.Functions versão do pacote 1.0.28 ou posterior
Microsoft.Extensions.DependencyInjection (atualmente, apenas a versão 2.x ou posterior suportada)
Serviços de registo
Para registrar serviços, crie um método para configurar e adicionar componentes a uma IFunctionsHostBuilder
instância. O host do Azure Functions cria uma instância de IFunctionsHostBuilder
e a passa diretamente para o seu método.
Advertência
Para aplicativos de função executados nos planos Consumo ou Premium, modificações nos valores de configuração usados em gatilhos podem causar erros de dimensionamento. Qualquer alteração destas propriedades pela classe FunctionsStartup
resulta num erro de inicialização da aplicação de função.
A injeção de IConfiguration
pode levar a um comportamento inesperado. Para saber mais sobre como adicionar fontes de configuração, consulte Personalizando fontes de configuração.
Para registrar o método, adicione o FunctionsStartup
atributo assembly que especifica o nome do tipo usado durante a inicialização.
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>();
}
}
Este exemplo utiliza o pacote Microsoft.Extensions.Http necessário para registrar HttpClient
no arranque.
Advertências
Uma série de etapas de registo é executada antes e depois do processo de execução processar a classe de inicialização. Portanto, tenha em mente os seguintes itens:
A classe de inicialização destina-se apenas à configuração e ao registro. Evite usar serviços registrados na inicialização durante o processo de inicialização. Por exemplo, não tente registrar uma mensagem em um registrador que está sendo registrado durante a inicialização. Este ponto do processo de registo é demasiado cedo para que os seus serviços estejam disponíveis para utilização. Depois que o
Configure
método é executado, o tempo de execução do Functions continua a registrar outras dependências, o que pode afetar como seus serviços operam.O contêiner de injeção de dependência contém apenas tipos explicitamente registrados. Os únicos serviços disponíveis como tipos injetáveis são os configurados no
Configure
método. Como resultado, tipos específicos de funções comoBindingContext
eExecutionContext
não estão disponíveis durante a configuração ou como tipos injetáveis.Não há suporte para a configuração da autenticação ASP.NET. O host Functions configura os serviços de autenticação do ASP.NET para expor corretamente as APIs para operações essenciais do ciclo de vida. Outras configurações em uma classe personalizada
Startup
podem substituir essa configuração, causando consequências indesejadas. Por exemplo, chamarbuilder.Services.AddAuthentication()
pode interromper a autenticação entre o portal e o host, levando a mensagens como o runtime do Azure Functions está inacessível.
Utilize dependências injetadas
A injeção de construtor é usada para tornar as suas dependências disponíveis numa função. O uso da injeção do construtor requer que você não use classes estáticas para serviços injetados ou para suas classes de função.
O exemplo a seguir demonstra como as dependências IMyService
e HttpClient
são injetadas numa função acionada por 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.");
}
}
Este exemplo utiliza o pacote Microsoft.Extensions.Http necessário para registrar HttpClient
no arranque.
Duração dos serviços
As aplicações do Azure Functions fornecem os mesmos tempos de vida de serviço que a injeção de dependência do ASP.NET. Para um aplicativo Functions, os diferentes tempos de vida do serviço se comportam da seguinte maneira:
- Transitório: Serviços transitórios são criados em cada resolução do serviço.
- Com Escopo: O tempo de vida de um serviço definido por escopo corresponde ao tempo de vida de execução de uma função. Os serviços com escopo são criados uma vez por execução de função. Solicitações posteriores para esse serviço durante a execução reutilizam a instância de serviço existente.
-
Singleton: O tempo de vida do serviço singleton corresponde ao tempo de vida do host e é reutilizado em execuções de função nessa instância. Recomenda-se o uso de serviços Singleton com tempo de vida para conexões e clientes, por exemplo, instâncias de
DocumentClient
ouHttpClient
.
Veja ou baixe uma amostra de diferentes tempos de vida de serviço no GitHub.
Serviços de registo
Se precisar de seu próprio provisionador de registo, registre um tipo personalizado como uma instância de ILoggerProvider
, que está disponível através do pacote NuGet Microsoft.Extensions.Logging.Abstractions.
O Application Insights é adicionado pelo Azure Functions automaticamente.
Advertência
- Não adicione
AddApplicationInsightsTelemetry()
à coleção de serviços, que registra serviços que entram em conflito com os serviços fornecidos pelo ambiente. - Não registre o seu próprio
TelemetryConfiguration
ouTelemetryClient
se você estiver usando a funcionalidade interna do Application Insights. Se você precisar configurar sua própriaTelemetryClient
instância, crie uma por meio da injetadaTelemetryConfiguration
, conforme mostrado em Telemetria personalizada de log em funções C#.
ILogger<T> e ILoggerFactory
O host injeta os serviços ILogger<T>
e ILoggerFactory
nos construtores. No entanto, por padrão, esses novos filtros de registo são excluídos dos registos de funções. Você precisa modificar o host.json
arquivo para optar por filtros e categorias extras.
O exemplo a seguir demonstra como adicionar um ILogger<HttpTrigger>
com logs que são expostos ao host.
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.");
// ...
}
O arquivo de exemplo host.json
a seguir adiciona o filtro de log.
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
},
"logLevel": {
"MyNamespace.HttpTrigger": "Information"
}
}
}
Para obter mais informações sobre níveis de log, consulte Configurar níveis de log.
Serviços fornecidos pelo aplicativo de função
O host da função registra muitos serviços. Os seguintes serviços são seguros para serem tomados como uma dependência em seu aplicativo:
Tipo de Serviço | Tempo de vida | Descrição |
---|---|---|
Microsoft.Extensions.Configuration.IConfiguration |
Singleton | Configuração de tempo de execução |
Microsoft.Azure.WebJobs.Host.Executors.IHostIdProvider |
Singleton | Responsável por fornecer o ID da instância do host |
Se houver outros serviços dos quais você deseja depender, crie um problema e proponha-os no GitHub.
Sobrescrevendo serviços de hospedagem
Atualmente, não há suporte para substituir serviços fornecidos pelo host. Se houver serviços que você deseja substituir, crie um problema e proponha-os no GitHub.
Trabalhar com opções e definições
Os valores definidos nas configurações do aplicativo estão disponíveis em uma IConfiguration
instância, o que permite que você leia os valores das configurações do aplicativo na classe de inicialização.
Você pode extrair valores da IConfiguration
instância para um tipo personalizado. Copiar os valores das configurações do aplicativo para um tipo personalizado facilita o teste de seus serviços, tornando esses valores injetáveis. As configurações lidas na instância de configuração devem ser pares chave/valor simples. Para funções executadas num plano Elastic Premium, os nomes de configuração da aplicação só podem conter letras, números (0-9
), pontos (.
), dois pontos (:
) e sublinhados (_
). Para obter mais informações, consulte Considerações sobre a configuração do aplicativo.
Considere a seguinte classe que inclui uma propriedade nomeada consistente com uma configuração de aplicativo:
public class MyOptions
{
public string MyCustomSetting { get; set; }
}
E um local.settings.json
arquivo que pode estruturar a configuração personalizada da seguinte maneira:
{
"IsEncrypted": false,
"Values": {
"MyOptions:MyCustomSetting": "Foobar"
}
}
Dentro do método Startup.Configure
, pode extrair valores da instância IConfiguration
para o seu tipo personalizado usando o seguinte código:
builder.Services.AddOptions<MyOptions>()
.Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("MyOptions").Bind(settings);
});
Ao chamar Bind
, os valores que têm nomes de propriedades correspondentes são copiados da configuração para a instância personalizada. A instância de opções agora está disponível no contêiner IoC para injetar em uma função.
O objeto options é injetado na função como uma instância da interface genérica IOptions
. Use a Value
propriedade para acessar os valores encontrados em sua configuração.
using System;
using Microsoft.Extensions.Options;
public class HttpTrigger
{
private readonly MyOptions _settings;
public HttpTrigger(IOptions<MyOptions> options)
{
_settings = options.Value;
}
}
Para obter mais informações, consulte Padrão de opções no ASP.NET Core.
Usando segredos de usuário do ASP.NET Core
Quando você desenvolve seu aplicativo localmente, o ASP.NET Core fornece uma ferramenta Secret Manager que permite armazenar informações secretas fora da raiz do projeto. Isso torna menos provável que os segredos sejam acidentalmente comprometidos com o controle da fonte. As Ferramentas Principais do Azure Functions (versão 3.0.3233 ou posterior) lêem automaticamente os segredos criados pelo ASP.NET Core Secret Manager.
Para configurar um projeto do .NET Azure Functions para usar segredos de usuário, execute o seguinte comando na raiz do projeto.
dotnet user-secrets init
Em seguida, use o dotnet user-secrets set
comando para criar ou atualizar segredos.
dotnet user-secrets set MySecret "my secret value"
Para acessar valores de segredos de usuário no código do aplicativo de função, use IConfiguration
ou IOptions
.
Personalizando fontes de configuração
Para especificar outras fontes de configuração, substitua o método ConfigureAppConfiguration
na classe StartUp
do seu aplicativo de função.
O exemplo seguinte adiciona valores de configuração a partir de ficheiros de definições de aplicações, tanto os gerais como os opcionais específicos ao ambiente.
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)
{
}
}
Adicione provedores de configuração à propriedade ConfigurationBuilder
de IFunctionsConfigurationBuilder
. Para obter mais informações sobre como usar provedores de configuração, consulte Configuração no ASP.NET Core.
A FunctionsHostBuilderContext
é obtido a partir de IFunctionsConfigurationBuilder.GetContext()
. Use esse contexto para recuperar o nome do ambiente atual e resolver o local dos arquivos de configuração na pasta do aplicativo de função.
Por padrão, os arquivos de configuração, como appsettings.json
não são copiados automaticamente para a pasta de saída do aplicativo de função. Atualize o .csproj
arquivo para corresponder ao exemplo a seguir para garantir que os arquivos sejam copiados.
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
Próximos passos
Para obter mais informações, consulte os seguintes recursos: