Desenvolver funções de biblioteca de classes C# usando o Azure Functions

Este artigo é uma introdução ao desenvolvimento do Azure Functions usando C# em bibliotecas de classes .NET.

Importante

Este artigo suporta funções de biblioteca de classes .NET que são executadas em processo com o tempo de execução. Suas funções C# também podem ser executadas fora do processo e isoladas do tempo de execução do Functions. O modelo de processo de trabalho isolado é a única maneira de executar versões não-LTS de aplicativos .NET e .NET Framework em versões atuais do tempo de execução do Functions. Para saber mais, consulte Funções isoladas do processo de trabalho do .NET. Para obter uma comparação abrangente entre o processo de trabalho isolado e as funções .NET em processo, consulte Diferenças entre o processo de trabalho em processo e o processo de trabalho isolado .NET Azure Functions.

Como desenvolvedor C#, você também pode estar interessado em um dos seguintes artigos:

Introdução Conceitos Aprendizagem guiada/amostras

O Azure Functions suporta linguagens de programação de script C# e C#. Se você estiver procurando orientação sobre como usar C# no portal do Azure, consulte Referência do desenvolvedor do script C# (.csx).

Versões suportadas

As versões do tempo de execução do Functions suportam versões específicas do .NET. Para saber mais sobre as versões do Functions, consulte Visão geral das versões de tempo de execução do Azure Functions. O suporte à versão também depende se suas funções são executadas no processo ou no processo de trabalho isolado.

Nota

Para saber como alterar a versão de tempo de execução do Functions usada pelo seu aplicativo de função, consulte Exibir e atualizar a versão atual do tempo de execução.

A tabela a seguir mostra o nível mais alto de .NET ou .NET Framework que pode ser usado com uma versão específica do Functions.

Versão do tempo de execução do Functions Processo de trabalho isolado
(.NET Isolado)
Em processo
(biblioteca de classes .NET)
Funções 4.x .NET 8.0
.NET 7.01
.NET 6.02
.NET Framework 4.83
.NET 6.02
Funções 1.x4 n/d .NET Framework 4.8

1 .NET 7 chega ao fim do suporte oficial em 14 de maio de 2024.
2 .NET 6 chega ao fim do suporte oficial em 12 de novembro de 2024.
3 O processo de compilação também requer o SDK do .NET 6.
4 O suporte termina para a versão 1.x do tempo de execução do Azure Functions em 14 de setembro de 2026. Para obter mais informações, consulte este anúncio de suporte. Para obter suporte total contínuo, você deve migrar seus aplicativos para a versão 4.x.

Para obter as últimas notícias sobre as versões do Azure Functions, incluindo a remoção de versões secundárias mais antigas específicas, monitore os anúncios do Serviço de Aplicativo do Azure.

Projeto de biblioteca de classes Functions

No Visual Studio, o modelo de projeto do Azure Functions cria um projeto de biblioteca de classes C# que contém os seguintes arquivos:

  • host.json - armazena definições de configuração que afetam todas as funções no projeto quando executado localmente ou no Azure.
  • local.settings.json - armazena configurações de aplicativos e cadeias de conexão que são usadas quando executadas localmente. Este ficheiro contém segredos e não é publicado na sua aplicação de função no Azure. Em vez disso, adicione as configurações do aplicativo ao seu aplicativo de função.

Quando você cria o projeto, uma estrutura de pastas que se parece com o exemplo a seguir é gerada no diretório de saída da compilação:

<framework.version>
 | - bin
 | - MyFirstFunction
 | | - function.json
 | - MySecondFunction
 | | - function.json
 | - host.json

Esse diretório é o que é implantado em seu aplicativo de função no Azure. As extensões de vinculação necessárias na versão 2.x do tempo de execução do Functions são adicionadas ao projeto como pacotes NuGet.

Importante

O processo de compilação cria um arquivo de function.json para cada função. Este ficheiro function.json não se destina a ser editado diretamente. Não é possível alterar a configuração de vinculação ou desativar a função editando este arquivo. Para saber como desativar uma função, consulte Como desativar funções.

Métodos reconhecidos como funções

Em uma biblioteca de classes, uma função é um método com um FunctionName atributo e um gatilho, conforme mostrado no exemplo a seguir:

public static class SimpleExample
{
    [FunctionName("QueueTrigger")]
    public static void Run(
        [QueueTrigger("myqueue-items")] string myQueueItem, 
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
    }
} 

O FunctionName atributo marca o método como um ponto de entrada de função. O nome deve ser exclusivo dentro de um projeto, começar com uma letra e conter apenas letras, _números e -, até 127 caracteres de comprimento. Os modelos de projeto geralmente criam um método chamado Run, mas o nome do método pode ser qualquer nome de método C# válido. O exemplo acima mostra um método estático sendo usado, mas as funções não precisam ser estáticas.

O atributo trigger especifica o tipo de gatilho e vincula os dados de entrada a um parâmetro de método. A função de exemplo é acionada por uma mensagem de fila e a mensagem de fila é passada para o método no myQueueItem parâmetro.

Parâmetros de assinatura do método

A assinatura do método pode conter parâmetros diferentes daquele usado com o atributo trigger. Aqui estão alguns dos outros parâmetros que você pode incluir:

A ordem dos parâmetros na assinatura da função não importa. Por exemplo, você pode colocar parâmetros de gatilho antes ou depois de outras associações e pode colocar o parâmetro do registrador antes ou depois dos parâmetros de gatilho ou vinculação.

Enlaces de saída

Uma função pode ter zero ou várias ligações de saída definidas usando parâmetros de saída.

O exemplo a seguir modifica o anterior adicionando uma ligação de fila de saída chamada myQueueItemCopy. A função grava o conteúdo da mensagem que dispara a função para uma nova mensagem em uma fila diferente.

public static class SimpleExampleWithOutput
{
    [FunctionName("CopyQueueMessage")]
    public static void Run(
        [QueueTrigger("myqueue-items-source")] string myQueueItem, 
        [Queue("myqueue-items-destination")] out string myQueueItemCopy,
        ILogger log)
    {
        log.LogInformation($"CopyQueueMessage function processed: {myQueueItem}");
        myQueueItemCopy = myQueueItem;
    }
}

Os valores atribuídos às ligações de saída são gravados quando a função é encerrada. Você pode usar mais de uma ligação de saída em uma função simplesmente atribuindo valores a vários parâmetros de saída.

Os artigos de referência de vinculação (filas de armazenamento, por exemplo) explicam quais tipos de parâmetros você pode usar com atributos de vinculação de gatilho, entrada ou saída.

Exemplo de expressões de vinculação

O código a seguir obtém o nome da fila a ser monitorada de uma configuração de aplicativo e obtém o tempo de criação da mensagem da fila insertionTime no parâmetro.

public static class BindingExpressionsExample
{
    [FunctionName("LogQueueMessage")]
    public static void Run(
        [QueueTrigger("%queueappsetting%")] string myQueueItem,
        DateTimeOffset insertionTime,
        ILogger log)
    {
        log.LogInformation($"Message content: {myQueueItem}");
        log.LogInformation($"Created at: {insertionTime}");
    }
}

function.json gerados automaticamente

O processo de compilação cria um arquivo de function.json em uma pasta de função na pasta de compilação. Como observado anteriormente, esse arquivo não deve ser editado diretamente. Não é possível alterar a configuração de vinculação ou desativar a função editando este arquivo.

O objetivo deste arquivo é fornecer informações ao controlador de escala para usar para decisões de dimensionamento no plano de consumo. Por esse motivo, o arquivo só tem informações de gatilho, não ligações de entrada/saída.

O arquivo de function.json gerado inclui uma configurationSource propriedade que informa ao tempo de execução para usar atributos .NET para associações, em vez de function.json configuração. Eis um exemplo:

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-1.0.0.0",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "queueTrigger",
      "queueName": "%input-queue-name%",
      "name": "myQueueItem"
    }
  ],
  "disabled": false,
  "scriptFile": "..\\bin\\FunctionApp1.dll",
  "entryPoint": "FunctionApp1.QueueTrigger.Run"
}

Microsoft.NET.Sdk.Funções

A geração de arquivos function.json é realizada pelo pacote NuGet Microsoft.NET.Sdk.Functions.

O exemplo a seguir mostra as partes relevantes dos .csproj arquivos que têm diferentes estruturas de destino do mesmo Sdk pacote:

<PropertyGroup>
  <TargetFramework>net6.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.1" />
</ItemGroup>

Entre as dependências do Sdk pacote estão gatilhos e associações. Um projeto 1.x refere-se a gatilhos e associações 1.x porque esses gatilhos e ligações visam o .NET Framework, enquanto os gatilhos e ligações 4.x visam o .NET Core.

O Sdk pacote também depende de Newtonsoft.Json, e indiretamente em WindowsAzure.Storage. Essas dependências garantem que seu projeto use as versões desses pacotes que funcionam com a versão de tempo de execução do Functions que o projeto destina. Por exemplo, Newtonsoft.Json tem a versão 11 para o .NET Framework 4.6.1, mas o tempo de execução do Functions destinado ao .NET Framework 4.6.1 só é compatível com Newtonsoft.Json o 9.0.1. Portanto, seu código de função nesse projeto também tem que usar Newtonsoft.Json 9.0.1.

O código-fonte para Microsoft.NET.Sdk.Functions está disponível no repositório do GitHub azure-functions-vs-build-sdk.

Versão do tempo de execução local

O Visual Studio usa as Ferramentas Principais do Azure Functions para executar projetos do Functions em seu computador local. As Ferramentas Principais são uma interface de linha de comando para o tempo de execução do Functions.

Se você instalar as Ferramentas Principais usando o pacote do instalador do Windows (MSI) ou usando npm, isso não afetará a versão das Ferramentas Principais usada pelo Visual Studio. Para o tempo de execução do Functions versão 1.x, o Visual Studio armazena versões das Ferramentas Principais em %USERPROFILE%\AppData\Local\Azure.Functions.Cli e usa a versão mais recente armazenada lá. Para o Functions 4.x, as Ferramentas Principais estão incluídas na extensão Azure Functions and Web Jobs Tools . Para o Functions 1.x, você pode ver qual versão está sendo usada na saída do console quando você executa um projeto do Functions:

[3/1/2018 9:59:53 AM] Starting Host (HostId=contoso2-1518597420, Version=2.0.11353.0, ProcessId=22020, Debug=False, Attempt=0, FunctionsExtensionVersion=)

ReadyToRun

Você pode compilar seu aplicativo de função como binários ReadyToRun. O ReadyToRun é uma forma de compilação antecipada que pode melhorar o desempenho da inicialização para ajudar a reduzir o impacto do arranque a frio quando executado em um plano de consumo.

O ReadyToRun está disponível no .NET 6 e versões posteriores e requer a versão 4.0 do tempo de execução do Azure Functions.

Para compilar seu projeto como ReadyToRun, atualize seu arquivo de projeto adicionando os <PublishReadyToRun> elementos e <RuntimeIdentifier> . A seguir está a configuração para publicação em um aplicativo de função de 32 bits do Windows.

<PropertyGroup>
  <TargetFramework>net6.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  <PublishReadyToRun>true</PublishReadyToRun>
  <RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>

Importante

A partir do .NET 6, foi adicionado suporte para a compilação Composite ReadyToRun. Confira as restrições de arquitetura e plataforma cruzada do ReadyToRun.

Você também pode criar seu aplicativo com ReadyToRun a partir da linha de comando. Para obter mais informações, consulte a -p:PublishReadyToRun=true opção em dotnet publish.

Tipos suportados para ligações

Cada ligação tem seus próprios tipos suportados; por exemplo, um atributo de gatilho de blob pode ser aplicado a um parâmetro string, um parâmetro POCO, um CloudBlockBlob parâmetro ou qualquer um dos vários outros tipos suportados. O artigo de referência de vinculação para associações de blob lista todos os tipos de parâmetros suportados. Para obter mais informações, consulte Gatilhos e ligações e os documentos de referência de vinculação para cada tipo de associação.

Gorjeta

Se você planeja usar as ligações HTTP ou WebHook, planeje evitar o esgotamento da porta que pode ser causado pela instanciação incorreta do HttpClient. Para obter mais informações, consulte Como gerenciar conexões no Azure Functions.

Vinculação ao valor de retorno do método

Você pode usar um valor de retorno de método para uma associação de saída, aplicando o atributo ao valor de retorno do método. Para obter exemplos, consulte Gatilhos e associações.

Use o valor de retorno somente se uma execução de função bem-sucedida sempre resultar em um valor de retorno para passar para a associação de saída. Caso contrário, use ICollector ou IAsyncCollector, conforme mostrado na seção a seguir.

Gravando vários valores de saída

Para gravar vários valores em uma ligação de saída, ou se uma invocação de função bem-sucedida pode não resultar em nada para passar para a associação de saída, use os ICollector tipos ou IAsyncCollector . Esses tipos são coleções somente gravação que são gravadas na associação de saída quando o método é concluído.

Este exemplo grava várias mensagens de fila na mesma fila usando ICollector:

public static class ICollectorExample
{
    [FunctionName("CopyQueueMessageICollector")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-3")] string myQueueItem,
        [Queue("myqueue-items-destination")] ICollector<string> myDestinationQueue,
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
        myDestinationQueue.Add($"Copy 1: {myQueueItem}");
        myDestinationQueue.Add($"Copy 2: {myQueueItem}");
    }
}

Assíncrono

Para tornar uma função assíncrona, use a async palavra-chave e retorne um Task objeto.

public static class AsyncExample
{
    [FunctionName("BlobCopy")]
    public static async Task RunAsync(
        [BlobTrigger("sample-images/{blobName}")] Stream blobInput,
        [Blob("sample-images-copies/{blobName}", FileAccess.Write)] Stream blobOutput,
        CancellationToken token,
        ILogger log)
    {
        log.LogInformation($"BlobCopy function processed.");
        await blobInput.CopyToAsync(blobOutput, 4096, token);
    }
}

Não é possível usar out parâmetros em funções assíncronas. Para ligações de saída, use o valor de retorno da função ou um objeto coletor.

Tokens de cancelamento

Uma função pode aceitar um parâmetro CancellationToken , que permite que o sistema operacional notifique seu código quando a função estiver prestes a ser encerrada. Você pode usar essa notificação para garantir que a função não seja encerrada inesperadamente de uma forma que deixe os dados em um estado inconsistente.

Considere o caso quando você tem uma função que processa mensagens em lotes. A seguinte função acionada pelo Barramento de Serviço do Azure processa uma matriz de objetos ServiceBusReceivedMessage, que representa um lote de mensagens de entrada a serem processadas por uma chamada de função específica:

using Azure.Messaging.ServiceBus;
using System.Threading;

namespace ServiceBusCancellationToken
{
    public static class servicebus
    {
        [FunctionName("servicebus")]
        public static void Run([ServiceBusTrigger("csharpguitar", Connection = "SB_CONN")]
               ServiceBusReceivedMessage[] messages, CancellationToken cancellationToken, ILogger log)
        {
            try
            { 
                foreach (var message in messages)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        log.LogInformation("A cancellation token was received. Taking precautionary actions.");
                        //Take precautions like noting how far along you are with processing the batch
                        log.LogInformation("Precautionary activities --complete--.");
                        break;
                    }
                    else
                    {
                        //business logic as usual
                        log.LogInformation($"Message: {message} was processed.");
                    }
                }
            }
            catch (Exception ex)
            {
                log.LogInformation($"Something unexpected happened: {ex.Message}");
            }
        }
    }
}

Registo

No código da função, você pode gravar a saída em logs que aparecem como rastreamentos no Application Insights. A maneira recomendada de gravar nos logs é incluir um parâmetro do tipo ILogger, que normalmente é chamado logde . Versão 1.x do tempo de execução do Functions usado TraceWriter, que também grava no Application Insights, mas não oferece suporte ao log estruturado. Não use Console.Write para gravar seus logs, pois esses dados não são capturados pelo Application Insights.

ILogger

Em sua definição de função, inclua um parâmetro ILogger , que suporta log estruturado.

Com um ILogger objeto, você chama Log<level>métodos de extensão no ILogger para criar logs. O código a seguir grava Information logs com categoria Function.<YOUR_FUNCTION_NAME>.User.:

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger logger)
{
    logger.LogInformation("Request for item with key={itemKey}.", id);

Para saber mais sobre como o Functions implementa , consulte Coletando dados de ILoggertelemetria. Categorias prefixadas com Function suposição de que você está usando uma ILogger instância. Se, em vez disso, optar por utilizar um ILogger<T>, o nome da categoria poderá basear-se em T.

Registos estruturados

A ordem dos espaços reservados, não seus nomes, determina quais parâmetros são usados na mensagem de log. Suponha que você tenha o seguinte código:

string partitionKey = "partitionKey";
string rowKey = "rowKey";
logger.LogInformation("partitionKey={partitionKey}, rowKey={rowKey}", partitionKey, rowKey);

Se você mantiver a mesma cadeia de caracteres de mensagem e inverter a ordem dos parâmetros, o texto da mensagem resultante terá os valores nos lugares errados.

Os espaços reservados são tratados dessa maneira para que você possa fazer o log estruturado. O Application Insights armazena os pares nome-valor do parâmetro e a cadeia de caracteres da mensagem. O resultado é que os argumentos da mensagem se tornam campos nos quais você pode consultar.

Se a chamada do método do registrador se parecer com o exemplo anterior, você poderá consultar o campo customDimensions.prop__rowKey. O prop__ prefixo é adicionado para garantir que não haja colisões entre campos que o tempo de execução adiciona e campos que seu código de função adiciona.

Você também pode consultar a cadeia de caracteres da mensagem original fazendo referência ao campo customDimensions.prop__{OriginalFormat}.

Aqui está um exemplo de representação JSON de customDimensions dados:

{
  "customDimensions": {
    "prop__{OriginalFormat}":"C# Queue trigger function processed: {message}",
    "Category":"Function",
    "LogLevel":"Information",
    "prop__message":"c9519cbf-b1e6-4b9b-bf24-cb7d10b1bb89"
  }
}

Telemetria personalizada de log

Há uma versão específica do SDK do Application Insights que você pode usar para enviar dados de telemetria personalizados de suas funções para o Application Insights: Microsoft.Azure.WebJobs.Logging.ApplicationInsights. Use o seguinte comando no prompt de comando para instalar este pacote:

dotnet add package Microsoft.Azure.WebJobs.Logging.ApplicationInsights --version <VERSION>

Neste comando, substitua <VERSION> por uma versão deste pacote que ofereça suporte à versão instalada do Microsoft.Azure.WebJobs.

Os exemplos de C# a seguir usam a API de telemetria personalizada. O exemplo é para uma biblioteca de classes .NET, mas o código do Application Insights é o mesmo para o script C#.

A versão 2.x e versões posteriores do tempo de execução usam recursos mais recentes no Application Insights para correlacionar automaticamente a telemetria com a operação atual. Não há necessidade de definir manualmente a operação Id, ParentIdou Name campos.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using System.Linq;

namespace functionapp0915
{
    public class HttpTrigger2
    {
        private readonly TelemetryClient telemetryClient;

        /// Using dependency injection will guarantee that you use the same configuration for telemetry collected automatically and manually.
        public HttpTrigger2(TelemetryConfiguration telemetryConfiguration)
        {
            this.telemetryClient = new TelemetryClient(telemetryConfiguration);
        }

        [FunctionName("HttpTrigger2")]
        public Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]
            HttpRequest req, ExecutionContext context, ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");
            DateTime start = DateTime.UtcNow;

            // Parse query parameter
            string name = req.Query
                .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
                .Value;

            // Write an event to the customEvents table.
            var evt = new EventTelemetry("Function called");
            evt.Context.User.Id = name;
            this.telemetryClient.TrackEvent(evt);

            // Generate a custom metric, in this case let's use ContentLength.
            this.telemetryClient.GetMetric("contentLength").TrackValue(req.ContentLength);

            // Log a custom dependency in the dependencies table.
            var dependency = new DependencyTelemetry
            {
                Name = "GET api/planets/1/",
                Target = "swapi.co",
                Data = "https://swapi.co/api/planets/1/",
                Timestamp = start,
                Duration = DateTime.UtcNow - start,
                Success = true
            };
            dependency.Context.User.Id = name;
            this.telemetryClient.TrackDependency(dependency);

            return Task.FromResult<IActionResult>(new OkResult());
        }
    }
}

Neste exemplo, os dados de métricas personalizadas são agregados pelo host antes de serem enviados para a tabela customMetrics. Para saber mais, consulte a documentação do GetMetric em Application Insights.

Ao executar localmente, você deve adicionar a APPINSIGHTS_INSTRUMENTATIONKEY configuração, com a chave do Application Insights, ao arquivo local.settings.json .

Não ligue TrackRequest ou StartOperation<RequestTelemetry> porque você verá solicitações duplicadas para uma chamada de função. O tempo de execução do Functions rastreia automaticamente as solicitações.

Não defina telemetryClient.Context.Operation.Id. Essa configuração global causa correlação incorreta quando muitas funções estão sendo executadas simultaneamente. Em vez disso, crie uma nova instância de telemetria (DependencyTelemetry, EventTelemetry) e modifique sua Context propriedade. Em seguida, passe a instância de telemetria para o método correspondente Track em TelemetryClient (TrackDependency(), TrackEvent()TrackMetric(), ). Esse método garante que a telemetria tenha os detalhes de correlação corretos para a chamada de função atual.

Testar funções

Os artigos a seguir mostram como executar uma função de biblioteca de classes C# em processo localmente para fins de teste:

Variáveis de ambiente

Para obter uma variável de ambiente ou um valor de configuração de aplicativo, use System.Environment.GetEnvironmentVariable, conforme mostrado no exemplo de código a seguir:

public static class EnvironmentVariablesExample
{
    [FunctionName("GetEnvironmentVariables")]
    public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
    {
        log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
        log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
        log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
    }

    private static string GetEnvironmentVariable(string name)
    {
        return name + ": " +
            System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
    }
}

As configurações do aplicativo podem ser lidas a partir de variáveis de ambiente ao desenvolver localmente e ao executar no Azure. Ao desenvolver localmente, as configurações do aplicativo vêm da Values coleção no arquivo local.settings.json. Em ambos os ambientes, local e Azure, GetEnvironmentVariable("<app setting name>") recupera o valor da configuração do aplicativo nomeado. Por exemplo, quando você estiver executando localmente, "Nome do Meu Site" será retornado se o arquivo local.settings.json contiver { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } }arquivos .

A propriedade System.Configuration.ConfigurationManager.AppSettings é uma API alternativa para obter valores de configuração de aplicativo, mas recomendamos que você use GetEnvironmentVariable conforme mostrado aqui.

Vinculação em tempo de execução

Em C# e outras linguagens .NET, você pode usar um padrão de vinculação imperativa , em oposição às associações declarativas em atributos. A vinculação imperativa é útil quando os parâmetros de vinculação precisam ser calculados em tempo de execução em vez de tempo de design. Com esse padrão, você pode vincular ligações de entrada e saída suportadas on-the-fly em seu código de função.

Defina uma ligação imperativa da seguinte forma:

  • Não inclua um atributo na assinatura da função para as ligações imperativas desejadas.

  • Passe um parâmetro Binder binder de entrada ou IBinder binder.

  • Use o seguinte padrão C# para executar a associação de dados.

    using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...)))
    {
        ...
    }
    

    BindingTypeAttribute é o atributo .NET que define sua associação e T é um tipo de entrada ou saída suportado por esse tipo de associação. T não pode ser um tipo de out parâmetro (como out JObject). Por exemplo, a vinculação de saída da tabela Aplicativos Móveis suporta seis tipos de saída, mas você só pode usar ICollector<T> ou IAsyncCollector<T> com vinculação imperativa.

Exemplo de atributo único

O código de exemplo a seguir cria uma ligação de saída de blob de armazenamento com caminho de blob definido em tempo de execução e, em seguida, grava uma cadeia de caracteres no blob.

public static class IBinderExample
{
    [FunctionName("CreateBlobUsingBinder")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-4")] string myQueueItem,
        IBinder binder,
        ILogger log)
    {
        log.LogInformation($"CreateBlobUsingBinder function processed: {myQueueItem}");
        using (var writer = binder.Bind<TextWriter>(new BlobAttribute(
                    $"samples-output/{myQueueItem}", FileAccess.Write)))
        {
            writer.Write("Hello World!");
        };
    }
}

BlobAttribute define a ligação de entrada ou saída do blob de armazenamento e TextWriter é um tipo de ligação de saída suportado.

Exemplo de vários atributos

O exemplo anterior obtém a configuração do aplicativo para a cadeia de conexão principal da conta de armazenamento do aplicativo de função (que é AzureWebJobsStorage). Você pode especificar uma configuração de aplicativo personalizada a ser usada para a conta de armazenamento adicionando o StorageAccountAttribute e passando a matriz de atributos para BindAsync<T>(). Use um Binder parâmetro, não IBinder. Por exemplo:

public static class IBinderExampleMultipleAttributes
{
    [FunctionName("CreateBlobInDifferentStorageAccount")]
    public async static Task RunAsync(
            [QueueTrigger("myqueue-items-source-binder2")] string myQueueItem,
            Binder binder,
            ILogger log)
    {
        log.LogInformation($"CreateBlobInDifferentStorageAccount function processed: {myQueueItem}");
        var attributes = new Attribute[]
        {
        new BlobAttribute($"samples-output/{myQueueItem}", FileAccess.Write),
        new StorageAccountAttribute("MyStorageAccount")
        };
        using (var writer = await binder.BindAsync<TextWriter>(attributes))
        {
            await writer.WriteAsync("Hello World!!");
        }
    }
}

Acionadores e enlaces

Esta tabela mostra as associações com suporte nas versões principais do tempo de execução do Azure Functions:

Type 1,x1 2.x e superior2 Acionador Entrada Saída
Armazenamento de blobs
BD do Cosmos para o Azure
Azure Data Explorer
SQL do Azure
Dapr4
Event Grid
Hubs de Eventos
HTTP & webhooks
Hub IoT
Kafka3
Aplicações Móveis
Hubs de Notificação
Armazenamento de filas
Redis
CoelhoMQ3
SendGrid
Service Bus
SignalR
Armazenamento de tabelas
Temporizador
Twilio

1 O suporte terminará para a versão 1.x do tempo de execução do Azure Functions em 14 de setembro de 2026. É altamente recomendável que você migre seus aplicativos para a versão 4.x para obter suporte completo.

2 A partir do tempo de execução da versão 2.x, todas as associações, exceto HTTP e Timer, devem ser registradas. Consulte Registrar extensões de vinculação.

3 Os gatilhos não são suportados no plano de consumo. Requer gatilhos controlados por tempo de execução.

4 Suportado apenas no Kubernetes, IoT Edge e outros modos auto-hospedados.

Próximos passos