Partilhar via


Desenvolver as Funções do Azure com o Visual Studio

O Visual Studio fornece uma maneira de desenvolver, testar e implantar funções de biblioteca de classes C# no Azure. Se esta experiência for a sua primeira com o Azure Functions, consulte Visão geral do Azure Functions.

Para começar imediatamente, considere concluir o guia de início rápido do Functions para Visual Studio.

Este artigo fornece informações detalhadas sobre como usar o Visual Studio para desenvolver funções de biblioteca de classes C# e publicá-las no Azure. Há dois modelos para desenvolver funções de biblioteca de classes C#: o modelo de trabalhador isolado e o modelo em processo.

Você está lendo a versão do modelo de trabalhador isolado deste artigo. Você pode selecionar seu modelo preferido no topo do artigo.

Você está lendo a versão do modelo em andamento deste artigo. Você pode selecionar seu modelo preferido no topo do artigo.

Salvo indicação em contrário, os procedimentos e exemplos mostrados são para o Visual Studio 2022. Para obter mais informações sobre as versões do Visual Studio 2022, consulte as notas de versão ou as notas de versão de visualização.

Pré-requisitos

  • Visual Studio 2022, incluindo a carga de trabalho de desenvolvimento Azure.

  • Outros recursos necessários, como uma conta de Armazenamento do Azure, são criados em sua assinatura durante o processo de publicação.

  • Se não tiver uma conta do Azure, crie uma conta gratuita antes de começar.

Criar um projeto das Funções do Azure

O modelo de projeto do Azure Functions no Visual Studio cria um projeto de biblioteca de classes C# que você pode publicar em um aplicativo de função no Azure. Você pode usar um aplicativo de função para agrupar funções como uma unidade lógica para facilitar o gerenciamento, a implantação, o dimensionamento e o compartilhamento de recursos.

  1. No menu Visual Studio, selecione Arquivo>>

  2. Na caixa de diálogo Criar um novo projeto , insira funções na caixa de pesquisa, selecione o modelo Azure Functions e selecione Avançar.

  3. Na caixa de diálogo Configurar seu novo projeto , para Nome do projeto, insira um nome para seu projeto e selecione Avançar. O nome da aplicação de funções deve ser válido como um espaço de nomes C#. Portanto, não use sublinhados, hífenes ou outros carateres não alfanuméricos.

  4. Na caixa de diálogo Informações adicionais , execute as ações listadas na tabela a seguir:

    Configuração Ação Descrição
    Funções de trabalhador Selecione .NET 8.0 Isolado (Suporte de longo prazo). Visual Studio cria um projeto de função que é executado em um processo de trabalho isolado. O processo de trabalho isolado também suporta outras versões do .NET e do .NET Framework que não oferecem suporte de longo prazo (LTS). Para obter mais informações, consulte Visão geral das versões de tempo de execução do Azure Functions.
    Function Selecione Http trigger. O Visual Studio cria uma função acionada por uma solicitação HTTP.
    Usar o Azurite para a conta de armazenamento em tempo de execução (AzureWebJobsStorage) Marque essa caixa de seleção. Como um aplicativo de função no Azure requer uma conta de armazenamento, uma é atribuída ou criada quando você publica seu projeto no Azure. Um gatilho HTTP não usa uma cadeia de conexão de conta de armazenamento. Todos os outros tipos de gatilho requerem uma cadeia de conexão de conta de armazenamento válida.
    Nível de autorização Selecione Anônimo. Quando você usa essa configuração de autorização, qualquer cliente pode acionar a função criada sem fornecer uma chave. Esta configuração facilita o teste da sua nova função. Para obter mais informações, consulte Nível de autorização.

    Captura de tela da caixa de diálogo Informações adicionais do Visual Studio que mostra as configurações configuradas, como uma versão isolada do .NET para o trabalhador Funções.

    Configuração Ação Descrição
    Funções de trabalhador Selecione .NET 8.0 Em processo (Suporte de longo prazo). O Visual Studio cria um projeto de função que é executado em processo com a versão 4.x do tempo de execução do Functions. Para obter mais informações, consulte Visão geral das versões de tempo de execução do Azure Functions.
    Function Selecione Http trigger. O Visual Studio cria uma função acionada por uma solicitação HTTP.
    Usar o Azurite para a conta de armazenamento em tempo de execução (AzureWebJobsStorage) Marque essa caixa de seleção. Como um aplicativo de função no Azure requer uma conta de armazenamento, uma é atribuída ou criada quando você publica seu projeto no Azure. Um gatilho HTTP não usa uma cadeia de conexão de conta de armazenamento. Todos os outros tipos de gatilho requerem uma cadeia de conexão de conta de armazenamento válida.
    Nível de autorização Selecione Anônimo Quando você usa essa configuração de autorização, qualquer cliente pode acionar a função criada sem fornecer uma chave. Esta configuração facilita o teste da sua nova função. Para obter mais informações, consulte Nível de autorização.

    Captura de tela da caixa de diálogo Informações adicionais do Visual Studio que mostra as configurações configuradas, como uma versão do .NET em processo para o operador de funções.

    Certifique-se de definir o nível de Autorização como Anônimo. Se selecionar o nível padrão de Função, será necessário apresentar a chave da função em solicitações para acessar o endpoint da função.

  5. Selecione Criar para criar o projeto de função e a função de gatilho HTTP.

Depois de criar um projeto do Functions, o modelo de projeto cria um projeto C#, instala os pacotes NuGet Microsoft.Azure.Functions.Worker e Microsoft.Azure.Functions.Worker.Sdk, e define o framework de destino.

Depois de criar um projeto do Functions, o modelo de projeto cria um projeto C#, instala o Microsoft.NET.Sdk.Functions pacote NuGet e define a estrutura de destino.

O novo projeto tem os seguintes arquivos:

  • host.json: Este arquivo fornece uma maneira de configurar o host Functions. Essas configurações se aplicam ao executar localmente e no Azure. Para obter mais informações, consulte host.json referência.

  • local.settings.json: Este arquivo mantém as configurações que você usa quando executa funções localmente. Essas configurações não são usadas quando seu aplicativo é executado no Azure. Para obter mais informações, consulte Trabalhar com configurações de aplicativo localmente.

    Importante

    Como o arquivo local.settings.json pode conter segredos, você deve excluí-lo do controle do código-fonte do projeto. Na caixa de diálogo Propriedades deste arquivo, verifique se a configuração Copiar para o diretório de saída está definida como Copiar se for mais recente.

Para obter mais informações, consulte Estrutura do projeto no guia do trabalhador isolado.

Para obter mais informações, consulte Projeto de biblioteca de classes Functions.

Trabalhar com as configurações do aplicativo localmente

Quando seu aplicativo de função é executado no Azure, as configurações exigidas por suas funções são armazenadas criptografadas nas configurações do aplicativo. Durante o desenvolvimento local, essas configurações são adicionadas à coleção Values no arquivo local.settings.json. O arquivo local.settings.json também armazena as configurações usadas pelas ferramentas de desenvolvimento local.

Os itens na Values coleção no arquivo local.settings.json do seu projeto destinam-se a espelhar itens nas definições da aplicação de funções no Azure.

O Visual Studio não carrega automaticamente as configurações no local.settings.json quando você publica o projeto. Para certificar-se de que essas configurações também existem em seu aplicativo de função no Azure, carregue-as depois de publicar seu projeto. Para obter mais informações, consulte Configurações do aplicativo de função. Os valores de uma ConnectionStrings coleção não são publicados.

Seu código também pode ler os valores de configurações do aplicativo de função como variáveis de ambiente. Para obter mais informações, consulte Variáveis de ambiente.

Configurar o projeto para desenvolvimento local

O runtime do Functions usa uma conta de armazenamento internamente. Durante o desenvolvimento, você pode usar uma conta de armazenamento válida para essa conta interna ou pode usar o emulador Azurite.

Para todos os tipos de gatilho diferentes de HTTP e webhooks, é necessário definir o valor da chave Values.AzureWebJobsStorage no ficheiro local.settings.json:

  • Para uma conta de armazenamento, ajuste o valor para a cadeia de conexão da sua conta de armazenamento.
  • Para o emulador, defina o valor como UseDevelopmentStorage=true.

Se você usar o emulador, altere essa configuração para uma cadeia de conexão de conta de armazenamento real antes da implantação. Para obter mais informações, consulte Emulador de armazenamento local.

Para definir a cadeia de conexão da conta de armazenamento, execute as seguintes etapas:

  1. Inicie sessão no portal do Azure e, em seguida, aceda à sua conta de armazenamento.

  2. Selecione Segurança + chaves de acesso à rede>. Em key1, copie o valor da cadeia de conexão.

  3. Em seu projeto do Visual Studio, abra o arquivo local.settings.json . Defina o valor da chave AzureWebJobsStorage para a cadeia de conexão que você copiou.

  4. Repita a etapa anterior para adicionar chaves exclusivas à Values matriz para quaisquer outras conexões exigidas por suas funções.

Adicionar uma função ao seu projeto

Nas funções da biblioteca de classes C#, as associações que as funções usam são definidas aplicando atributos no código. Quando você cria seus gatilhos de função a partir dos modelos fornecidos, os atributos de gatilho são aplicados para você.

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no nó do projeto e selecione > do Azure.

  2. Na caixa de diálogo Adicionar Novo Item , selecione Função do Azure e, em seguida, selecione Adicionar.

  3. Selecione um gatilho e defina as propriedades de vinculação necessárias. Se selecionar um trigger de serviço de armazenamento e quiser configurar a conexão, marque a caixa de seleção para configurar a conexão do trigger. O exemplo a seguir mostra as configurações para criar uma função de gatilho de Armazenamento de Filas.

    Captura de ecrã da caixa de diálogo Nova Função do Azure para um disparador de fila, com o nome da cadeia de conexão definido como QueueStorage e a fila definida como myqueue-items.

  4. Selecione Adicionar. Se você marcar a caixa de seleção para configurar uma conexão de armazenamento na etapa anterior, a página Conectar à dependência será exibida. Selecione um emulador de armazenamento Azurite ou Armazenamento do Azure e, em seguida, selecione Avançar.

    • Se você selecionar um emulador de armazenamento Azurite, a página Conectar ao emulador de Azurite de Armazenamento será exibida. Siga os seguintes passos:
      1. Selecione Avançar.
      2. Na página Resumo das alterações , selecione Concluir. O Visual Studio configura a dependência e cria a classe de gatilho.
    • Se você selecionar Armazenamento do Azure, a página Conectar ao Armazenamento do Azure será exibida. Siga os seguintes passos:
      1. Selecione uma conta de armazenamento e, em seguida, selecione Avançar. O Visual Studio tenta conectar-se à sua conta Azure e recuperar um endpoint.
      2. Selecione Avançar.
      3. Na página Resumo das alterações , selecione Concluir. O Visual Studio configura a dependência e cria a classe de gatilho.

    Este exemplo de gatilho usa uma configuração de aplicativo para a conexão de armazenamento com uma chave chamada QueueStorage. Essa chave, armazenada no arquivolocal.settings.json, faz referência ao emulador Azurite ou a uma conta de armazenamento.

  5. Examine a classe recém-adicionada. Por exemplo, a seguinte classe C# representa uma função básica de gatilho de armazenamento de fila:

    Um Run() método é atribuído com Function. Este atributo indica que o método é o ponto de entrada para a função.

    using System;
    using Azure.Storage.Queues.Models;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.Logging;
    
    namespace Company.Function;
    
    public class QueueTriggerCSharp
    {
        private readonly ILogger<QueueTriggerCSharp> _logger;
    
        public QueueTriggerCSharp(ILogger<QueueTriggerCSharp> logger)
        {
            _logger = logger;
        }
    
        [Function(nameof(QueueTriggerCSharp))]
        public void Run([QueueTrigger("PathValue", Connection = "ConnectionValue")] QueueMessage message)
        {
            _logger.LogInformation("C# Queue trigger function processed: {messageText}", message.MessageText);
        }
    }
    

    Um método estático Run() é atribuído com FunctionName. Este atributo indica que o método é o ponto de entrada para a função.

    using System;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Host;
    using Microsoft.Extensions.Logging;
    
    namespace Company.Function
    {
        public class QueueTriggerCSharp
        {
            [FunctionName("QueueTriggerCSharp")]
            public void Run([QueueTrigger("PathValue", Connection = "ConnectionValue")]string myQueueItem, ILogger log)
            {
                log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
            }
        }
    }
    

Um atributo específico de ligação é aplicado a cada parâmetro de ligação fornecido ao método de ponto de entrada. O atributo usa as informações de vinculação como parâmetros.

No código anterior, o primeiro parâmetro tem um atributo QueueTrigger aplicado, que indica uma função de gatilho do Armazenamento em Fila. O nome da fila e o nome da configuração da cadeia de conexão são passados como parâmetros para o QueueTrigger atributo. Na sua turma:

  • O parâmetro queue name deve corresponder ao nome da fila usada em uma etapa anterior para criar o gatilho, como myqueue-items.
  • O nome da configuração da cadeia de conexão deve corresponder ao que você usa em uma etapa anterior para criar o gatilho, como QueueStorage.

Para obter mais informações, consulte Trigger de armazenamento de filas do Azure para Azure Functions.

Use o procedimento anterior para adicionar mais funções ao seu projeto de aplicativo de função. Cada função no projeto pode ter um gatilho diferente, mas uma função deve ter exatamente um gatilho. Para obter mais informações, consulte Gatilhos e associações do Azure Functions.

Adicionar enlaces

Assim como acontece com os gatilhos, as ligações de entrada e saída são adicionadas à sua função como atributos de ligação. Para adicionar associações a uma função, execute as seguintes etapas:

  1. Certifique-se de configurar o projeto para desenvolvimento local.

  2. Adicione o pacote de extensão NuGet apropriado para cada associação específica. Para obter os requisitos específicos do pacote NuGet de vinculação, consulte o artigo de referência para a vinculação. Por exemplo, para requisitos de pacote para o gatilho de Hubs de Eventos do Azure, consulte Gatilho e associações de Hubs de Eventos do Azure para o Azure Functions.

  3. Use o seguinte comando no Console do Gerenciador de Pacotes para instalar um pacote específico:

    Install-Package Microsoft.Azure.Functions.Worker.Extensions.<BINDING_TYPE> -Version <TARGET_VERSION>
    
    Install-Package Microsoft.Azure.WebJobs.Extensions.<BINDING_TYPE> -Version <TARGET_VERSION>
    

    Neste código, substitua <BINDING_TYPE> pelo nome específico da extensão de vinculação e substitua <TARGET_VERSION> por uma versão específica do pacote, como 4.0.0. As versões válidas estão listadas nas páginas de pacotes individuais em NuGet.org.

  4. Se houver configurações de aplicativo que a associação precisa, adicione-as Values à coleção no arquivo de configuração local.

    A função usa esses valores quando é executada localmente. Quando a função é executada no aplicativo de função no Azure, ela usa as configurações do aplicativo de função. O Visual Studio facilita a publicação de configurações locais no Azure.

  5. Adicione o atributo de vinculação apropriado à assinatura do método. No código a seguir, uma mensagem de fila ativa a função Run. Em seguida, a associação de saída cria uma nova mensagem de fila com o mesmo texto em uma fila diferente.

     public class QueueTrigger
    {
        private readonly ILogger _logger;
    
        public QueueTrigger(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<QueueTrigger>();
        }
    
        [Function("CopyQueueMessage")]
        [QueueOutput("myqueue-items-destination", Connection = "QueueStorage")]
        public string Run([QueueTrigger("myqueue-items-source", Connection = "QueueStorage")] string myQueueItem)
        {
            _logger.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
            return myQueueItem;
        }
    }
    

    O QueueOutput atributo define a ligação no método. Para várias ligações de saída, em vez disso, você coloca esse atributo em uma propriedade string do objeto retornado. Para obter mais informações, consulte Ligações de saída múltiplas.

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

    O atributo Queue no parâmetro out define a ligação de saída.

    A conexão com o Armazenamento em Fila é obtida a partir da configuração QueueStorage. Para obter mais informações, consulte o artigo de referência para a vinculação específica.

Para obter uma lista completa das associações suportadas pelo Functions, consulte Ligações suportadas. Para obter um exemplo mais completo desse cenário, consulte Conectar funções ao Armazenamento do Azure usando o Visual Studio.

Executar funções localmente

Você pode usar as Ferramentas Principais do Azure Functions para executar projetos do Functions em seu computador de desenvolvimento local. Quando você seleciona F5 para depurar um projeto do Functions, o host local do Functions (func.exe) começa a escutar em uma porta local (geralmente 7071). Todos os endpoints de funções que podem ser chamadas são gravados na saída, e você pode usar esses endpoints para testar suas funções. Para obter mais informações, consulte Desenvolver o Azure Functions localmente usando as ferramentas principais. Você será solicitado a instalar essas ferramentas na primeira vez que iniciar uma função do Visual Studio.

Importante

A partir da versão 4.0.6517 das Ferramentas Principais, os projetos de modelo em processo devem fazer referência à versão 4.5.0 ou posterior do Microsoft.NET.Sdk.Functions. Se utilizar uma versão anterior, o comando func start gera um erro.

Para iniciar sua função no Visual Studio no modo de depuração, execute as seguintes etapas:

  1. Selecione F5. Se solicitado, aceite a solicitação do Visual Studio para baixar e instalar as Ferramentas Principais do Azure Functions. Também pode ser necessário ativar uma exceção de firewall para que as ferramentas possam lidar com solicitações HTTP.

  2. Quando o projeto é executado, teste seu código da mesma forma que você testa uma função implantada.

    Ao executar o Visual Studio no modo de depuração, os pontos de interrupção são atingidos conforme o esperado.

Para obter um cenário de teste mais detalhado que usa o Visual Studio, consulte Funções de teste, mais adiante neste artigo.

Publicar no Azure

Quando você publica seu projeto do Functions no Azure, o Visual Studio usa a implantação zip para implantar os arquivos de projeto. Quando possível, você também deve selecionar Executar do arquivo de pacote para que o projeto seja executado no pacote de implantação (.zip). Para obter mais informações, consulte Executar suas funções a partir de um arquivo de pacote no Azure.

Não implante em Functions utilizando o Web Deploy (msdeploy).

Use as seguintes etapas para publicar seu projeto em um aplicativo de função no Azure:

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Publicar.

  2. Na página Publicar , faça as seguintes seleções:

    • No Destino, selecione Azure e, em seguida, selecione Avançar.
    • Em Destino específico, selecione Azure Function App e, em seguida, selecione Avançar.
    • Na instância Functions, selecione Create new.

    Captura de ecrã da página Publicar. Na seção Instância de funções, um grupo de recursos é visível e Criar novo é realçado.

  3. Crie uma nova instância usando os valores especificados na tabela a seguir:

    Configuração valor Descrição
    Nome Um nome único globalmente O nome deve identificar exclusivamente seu novo aplicativo de função. Aceite o nome sugerido ou insira um novo nome. Os seguintes caracteres são válidos: a-z, 0-9, e -.
    Nome da subscrição O nome da sua subscrição O aplicativo de função é criado em uma assinatura do Azure. Aceite a assinatura padrão ou selecione uma diferente na lista.
    Grupo de recursos O nome do seu grupo de recursos A aplicação de função é criada num grupo de recursos. Selecione Novo para criar um novo grupo de recursos. Você também pode selecionar um grupo de recursos existente na lista.
    Tipo de Plano Consumo Flexível Quando você publica seu projeto em um aplicativo de função executado em um plano Flex Consumption, você pode pagar apenas pelas execuções do seu aplicativo de funções. Outros planos de hospedagem podem incorrer em custos mais altos.
    IMPORTANTE:
    Ao criar um plano Flex Consumption, você deve primeiro selecionar Plano de serviço de aplicativo e, em seguida, selecionar novamente Flex Consumption para eliminar um problema com a caixa de diálogo.
    Sistema Operativo Linux O plano Flex Consumption atualmente requer Linux.
    Localização A localização do serviço de aplicativo Selecione um local em uma região do Azure suportada pelo plano Flex Consumption. Quando uma região sem suporte é selecionada, o botão Criar fica acinzentado.
    Tamanho da memória da instância 2048 O tamanho da memória das instâncias de máquina virtual nas quais o aplicativo é executado é exclusivo do plano Flex Consumption.
    Armazenamento do Azure Uma conta de armazenamento de uso geral O tempo de execução do Functions requer uma conta de armazenamento. Selecione Novo para configurar uma conta de armazenamento de uso geral. Você também pode usar uma conta existente que atenda aos requisitos da conta de armazenamento.
    Informações sobre aplicativos Uma instância do Application Insights Você deve ativar a integração do Application Insights para seu aplicativo de função. Selecione Novo para criar uma nova instância, em um espaço de trabalho novo ou existente do Log Analytics. Você também pode usar uma instância existente.

    Captura de ecrã da caixa de diálogo Criar nova aplicação de funções. Os campos para o nome, assinatura, grupo de recursos, plano e outras configurações são preenchidos.

  4. Selecione Criar para criar um aplicativo de função e seus recursos relacionados no Azure. O status da criação de recursos é mostrado no canto inferior esquerdo da janela.

  5. Selecione Concluir. A janela Publicar progresso da criação do perfil é exibida. Quando o perfil for criado, selecione Fechar.

  6. Na página de perfil de publicação, selecione Publicar para implantar o pacote que contém seus arquivos de projeto em seu novo aplicativo de função no Azure.

    Quando a implantação estiver concluída, a URL raiz do aplicativo de função no Azure será mostrada na página de perfil de publicação.

  7. Na página de perfil de publicação, vá para a seção Hospedagem . Selecione as reticências (...) e, em seguida, selecione Abrir no portal do Azure. O novo recurso do aplicativo de função do Azure é aberto no portal do Azure.

    Captura de ecrã da página de perfil de publicação. Na seção Hospedagem, o menu de atalho de reticências está aberto e Abrir no portal do Azure está realçado.

Definições da aplicação de função

O Visual Studio não carrega as configurações do aplicativo automaticamente quando você publica seu projeto. Se você adicionar configurações ao arquivo local.settings.json , também deverá adicioná-las ao aplicativo de função no Azure.

A maneira mais fácil de carregar as configurações necessárias para seu aplicativo de função no Azure é gerenciá-las no Visual Studio. Na página de perfil de publicação, vá para a seção Hospedagem . Selecione as reticências (...) e, em seguida, selecione Gerenciar configurações do Serviço de Aplicativo do Azure.

Captura de ecrã da secção de Hospedagem na página de perfil de publicação. O menu de opções com reticências está aberto e Gerir as configurações do Serviço de Aplicações do Azure está destacado.

Quando você faz a seleção, a caixa de diálogo Configurações do aplicativo é aberta para o aplicativo de função. Você pode usar essa caixa de diálogo para adicionar configurações do aplicativo ou modificar as existentes.

Captura de tela da caixa de diálogo Configurações do aplicativo que mostra valores locais e remotos para várias configurações e controles para adicionar e editar valores.

Para cada configuração, o valor Local é o valor no arquivo local.settings.json e o valor Remote é o valor no aplicativo de função no Azure.

  • Para criar uma configuração de aplicativo, selecione Adicionar configuração.
  • Para copiar um valor de configuração do campo Local para o campo Remoto , selecione Inserir valor de Local.

As alterações pendentes são gravadas no arquivo de configurações local e no aplicativo de função quando você seleciona OK.

Nota

Por predefinição, o ficheirolocal.settings.jsonnão é registado no controlo de versão. Como resultado, se clonar um projeto Functions local do controlo de origem, o projeto não terá um arquivo local.settings.json. Você precisa criar manualmente o arquivo local.settings.json na raiz do projeto para que a caixa de diálogo Configurações do aplicativo funcione conforme o esperado.

Você também pode gerenciar as configurações do aplicativo de uma destas outras maneiras:

Depuração remota

Para depurar remotamente a sua aplicação de funções, deve publicar uma configuração de depuração do seu projeto. Você também precisa ativar a depuração remota na sua aplicação de funções no Azure.

Esta seção pressupõe que uma configuração de debug para a sua aplicação de funções esteja publicada.

Considerações sobre depuração remota

  • A depuração remota não é recomendada num serviço de produção.
  • Para usar a depuração remota, você deve hospedar seu aplicativo de função em um plano Premium ou do Serviço de Aplicativo.
  • Atualmente, a depuração remota só é suportada ao executar seu aplicativo C# no Windows.
  • Se você tiver o recurso Apenas Meu Código ativado no Visual Studio, desative-o. Para obter instruções, consulte Ativar ou desativar Apenas Meu Código.
  • Evite longas paradas em pontos de interrupção ao usar a depuração remota. Quando um processo é interrompido por mais do que alguns minutos, o Azure o trata como um processo sem resposta e o desliga.
  • Enquanto você está depurando, o servidor envia dados para o Visual Studio, o que pode afetar as cobranças de largura de banda. Para obter informações sobre taxas de largura de banda, consulte Calculadora de preços.
  • A depuração remota é desativada automaticamente na sua aplicação de função após 48 horas. Após esse ponto, você precisa ativar novamente a depuração remota.

Anexar o depurador

Quando depura uma aplicação de processo de trabalho isolado, atualmente é necessário anexar o depurador remoto a um processo .NET separado. Várias outras etapas de configuração também são necessárias.

Para anexar um depurador remoto a um aplicativo de função em execução em um processo separado do host Functions, execute as seguintes etapas:

  1. Na página de perfil de publicação, vá para a seção Hospedagem . Selecione a omissão (...) e, em seguida, selecione Anexar depurador.

    O Visual Studio conecta-se à sua aplicação de funções e ativa a depuração remota se ainda não estiver ativada.

    Nota

    Como o depurador remoto não pode se conectar ao processo de host, uma mensagem de erro pode aparecer. Em qualquer caso, o depurador local não pode acessar seus pontos de interrupção ou fornecer uma maneira de inspecionar variáveis ou percorrer o código.

  2. No menu Depurar do Visual Studio, selecione Anexar ao processo.

  3. Na caixa de diálogo Anexar ao processo , execute as seguintes etapas:

    1. Ao lado de Tipo de conexão, selecione Serviços de Aplicativo do Microsoft Azure.
    2. Ao lado de Destino da conexão, selecione Localizar.
  4. Na caixa de diálogo Anexar ao Processo do Azure, procure e selecione seu aplicativo de função e selecione OK.

  5. Se solicitado, permita o acesso ao Visual Studio por meio do firewall local.

  6. De volta à caixa de diálogo Anexar ao processo , selecione Mostrar processos para todos os usuários. Selecione dotnet.exee, em seguida, selecione Anexar.

    Captura de ecrã da caixa de diálogo Anexar ao Processo. O tipo de conexão é Serviços de Aplicativo do Microsoft Azure. Na tabela de processos, dotnet.exe está selecionado.

Quando a operação terminar, você será anexado ao código da biblioteca de classes C# em execução em um processo de trabalho isolado. Neste ponto, pode depurar a sua aplicação de função normalmente.

Para anexar um depurador remoto a um aplicativo de função em execução dentro do processo com o host Functions, execute as etapas a seguir.

Na página de perfil de publicação, vá para a seção Hospedagem . Selecione a omissão (...) e, em seguida, selecione Anexar depurador.

O Visual Studio conecta-se à sua aplicação de funções e ativa a depuração remota se ainda não estiver ativada. Ele também localiza e anexa o depurador ao processo anfitrião do aplicativo. Neste ponto, pode depurar a sua aplicação de função normalmente.

Quando terminar a depuração, você deve desativar a depuração remota.

Desativar a depuração remota

Depois de concluir a depuração remota do código, você deve desativar a depuração remota no portal do Azure. A depuração remota é desativada automaticamente após 48 horas, caso te esqueças.

  1. Na página de perfil de publicação, vá para a seção Hospedagem . Selecione as reticências (...) e, em seguida, selecione Abrir no portal do Azure. O portal do Azure abre na aplicação de função onde o seu projeto está implantado.

  2. Na aplicação de funções, selecioneConfiguração de Definições> e, em seguida, aceda ao separador Definições gerais. Ao lado de Depuração remota, selecione Desativado. Selecione Guardar e, em seguida, selecione Continuar.

Depois que o aplicativo de função for reiniciado, você não poderá mais se conectar remotamente aos seus processos remotos. Você pode usar essa mesma guia no portal do Azure para ativar a depuração remota fora do Visual Studio.

Funções de monitorização

A maneira recomendada de monitorar suas funções é integrando seu aplicativo de funções com o Application Insights. Você deve ativar essa integração ao criar seu aplicativo de função durante a publicação do Visual Studio.

Se a integração não estiver configurada durante a publicação por algum motivo, você ainda deverá ativar a integração do Application Insights para seu aplicativo de função no Azure.

Para obter mais informações sobre como usar o Application Insights para monitoramento, consulte Monitorar execuções no Azure Functions.

Funções de teste

Esta seção descreve como criar um projeto de modelo em processo em C# que você pode testar usando xUnit, uma ferramenta de teste de unidade de código aberto para .NET.

Passo 1: Configuração

Siga estas etapas para configurar o ambiente, incluindo o projeto e as funções do aplicativo, necessários para dar suporte aos testes:

  1. No Visual Studio, crie um projeto do Azure Functions chamado Functions.

  2. Crie uma função HTTP a partir do modelo:

    1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto Functions e selecione Adicionar>Nova Função do Azure.
    2. Na caixa de diálogo Adicionar Novo Item , selecione Função do Azure e, em seguida, selecione Adicionar.
    3. Selecione Gatilho Http e, em seguida, selecione Adicionar.
    4. Renomeie a nova classe MyHttpTrigger.
  3. Crie uma função de temporizador a partir do modelo:

    1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto Functions e selecione Adicionar>Nova Função do Azure.
    2. Na caixa de diálogo Adicionar Novo Item , selecione Função do Azure e, em seguida, selecione Adicionar.
    3. Selecione Gatilho de temporizador e, em seguida, selecione Adicionar.
    4. Renomeie a nova classe MyTimerTrigger.
  4. Crie um aplicativo xUnit Test na solução:

    1. No Gerenciador de Soluções, clique com o botão direito do mouse na solução que contém seu projeto Functions e selecione Adicionar>Novo Projeto.
    2. Selecione o modelo xUnit Test Project e, em seguida, selecione Next.
    3. Nomeie o projeto Functions.Tests.
  5. Remova os arquivos de teste padrão do projeto Functions.Tests .

  6. Use o NuGet para adicionar uma referência do aplicativo de teste a Microsoft.AspNetCore.Mvc. Você pode usar o Console do Gerenciador de Pacotes ou executar as seguintes etapas:

    1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto Functions.Tests e selecione Gerenciar Pacotes NuGet.
    2. Procure e instale Microsoft.AspNetCore.Mvc.
  7. No aplicativo Functions.Tests , adicione uma referência ao aplicativo Functions :

    1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto Functions.Tests e selecione Adicionar>Referência de Projeto.
    2. Selecione o projeto Functions e, em seguida, selecione OK.

Etapa 2: Criar classes de teste

Nesta seção, você cria as classes que você usa para executar os testes automatizados.

Cada função requer uma implementação de ILogger para lidar com o registo de mensagens. Em alguns testes, nenhuma mensagem é registrada, ou não importa como o registro é implementado. Outros testes precisam avaliar as mensagens registradas para determinar se um teste deve ser aprovado.

  1. Crie uma classe em seu projeto Functions.Tests nomeado NullScope e adicione o código a seguir. Esta classe fornece um escopo simulado. Em uma etapa posterior, você cria uma implementação de ILogger que usa esse escopo.

    using System;
    
    namespace Functions.Tests
    {
        public class NullScope : IDisposable
        {
            public static NullScope Instance { get; } = new NullScope();
    
            private NullScope() { }
    
            public void Dispose() { }
        }
    }
    
  2. Crie uma classe em seu projeto Functions.Tests nomeado ListLogger e adicione o código a seguir. Essa classe mantém uma lista interna de mensagens para avaliar durante o teste. Para implementar a interface necessária ILogger , a classe usa o escopo simulado da NullScope classe. Os casos de teste passam o escopo simulado para a ListLogger classe.

    using Microsoft.Extensions.Logging;
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Functions.Tests
    {
        public class ListLogger : ILogger
        {
            public IList<string> Logs;
    
            public IDisposable BeginScope<TState>(TState state) => NullScope.Instance;
    
            public bool IsEnabled(LogLevel logLevel) => false;
    
            public ListLogger()
            {
                this.Logs = new List<string>();
            }
    
            public void Log<TState>(LogLevel logLevel,
                                    EventId eventId,
                                    TState state,
                                    Exception exception,
                                    Func<TState, Exception, string> formatter)
            {
                string message = formatter(state, exception);
                this.Logs.Add(message);
            }
        }
    }
    

    A ListLogger classe implementa os seguintes membros, conforme estabelecido pela ILogger interface.

    • BeginScope: Os escopos adicionam contexto ao seu registro. Nesse caso, o teste aponta para a instância estática na NullScope classe para permitir que o teste funcione.
    • IsEnabled: Um valor padrão de false é fornecido.
    • Log: Este método usa a função fornecida formatter para formatar a mensagem. Em seguida, o Logs método adiciona o texto resultante à coleção.

    A coleção Logs é uma instância de List<string> e é inicializada no construtor.

  3. Crie um arquivo de código no projeto Functions.Tests chamado LoggerTypes.cs e adicione o seguinte código:

    namespace Functions.Tests
    {
        public enum LoggerTypes
        {
            Null,
            List
        }
    }
    

    Essa enumeração especifica o tipo de logger que os testes usam.

  4. Crie uma classe no projeto Functions.Tests nomeado TestFactory e adicione o seguinte código:

    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Http.Internal;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Logging.Abstractions;
    using Microsoft.Extensions.Primitives;
    using System.Collections.Generic;
    
    namespace Functions.Tests
    {
        public class TestFactory
        {
            public static IEnumerable<object[]> Data()
            {
                return new List<object[]>
                {
                    new object[] { "name", "Bernardo" },
                    new object[] { "name", "Ananya" },
                    new object[] { "name", "Vlad" }
    
                };
            }
    
            private static Dictionary<string, StringValues> CreateDictionary(string key, string value)
            {
                var qs = new Dictionary<string, StringValues>
                {
                    { key, value }
                };
                return qs;
            }
    
            public static HttpRequest CreateHttpRequest(string queryStringKey, string queryStringValue)
            {
                var context = new DefaultHttpContext();
                var request = context.Request;
                request.Query = new QueryCollection(CreateDictionary(queryStringKey, queryStringValue));
                return request;
            }
    
            public static ILogger CreateLogger(LoggerTypes type = LoggerTypes.Null)
            {
                ILogger logger;
    
                if (type == LoggerTypes.List)
                {
                    logger = new ListLogger();
                }
                else
                {
                    logger = NullLoggerFactory.Instance.CreateLogger("Null Logger");
                }
    
                return logger;
            }
        }
    }
    

    A TestFactory classe implementa os seguintes membros:

    • Data: Esta propriedade retorna uma coleção IEnumerable de dados de exemplo. Os pares chave-valor representam valores que são passados para uma string de consulta.
    • CreateDictionary: Este método aceita um par chave-valor como um argumento. Ele retorna uma nova instância de Dictionary, que é usada para criar uma instância de QueryCollection para representar valores de cadeia de consulta.
    • CreateHttpRequest: Este método cria uma solicitação HTTP que é inicializada com os parâmetros de cadeia de caracteres de consulta fornecidos.
    • CreateLogger: Este método retorna uma implementação de ILogger que é usada para teste. A ILogger implementação depende do tipo de logger especificado. Se um tipo de lista for especificado, a instância ListLogger mantém o registo das mensagens registadas que estão disponíveis para avaliação em testes.
  5. Crie uma classe no projeto Functions.Tests nomeado FunctionsTests e adicione o seguinte código:

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    using Xunit;
    
    namespace Functions.Tests
    {
        public class FunctionsTests
        {
            private readonly ILogger logger = TestFactory.CreateLogger();
    
            [Fact]
            public async void Http_trigger_should_return_known_string()
            {
                var request = TestFactory.CreateHttpRequest("name", "Bernardo");
                var response = (OkObjectResult)await MyHttpTrigger.Run(request, logger);
                Assert.Equal("Hello, Bernardo. This HTTP triggered function executed successfully.", response.Value);
            }
    
            [Theory]
            [MemberData(nameof(TestFactory.Data), MemberType = typeof(TestFactory))]
            public async void Http_trigger_should_return_known_string_from_member_data(string queryStringKey, string queryStringValue)
            {
                var request = TestFactory.CreateHttpRequest(queryStringKey, queryStringValue);
                var response = (OkObjectResult)await MyHttpTrigger.Run(request, logger);
                Assert.Equal($"Hello, {queryStringValue}. This HTTP triggered function executed successfully.", response.Value);
            }
    
            [Fact]
            public void Timer_should_log_message()
            {
                var logger = (ListLogger)TestFactory.CreateLogger(LoggerTypes.List);
                new MyTimerTrigger().Run(null, logger);
                var msg = logger.Logs[0];
                Assert.Contains("C# Timer trigger function executed at", msg);
            }
        }
    }
    

    Esta classe implementa os seguintes membros:

    • Http_trigger_should_return_known_string: Este teste usa o valor name=Bernardo da cadeia de caracteres de consulta para criar uma solicitação para uma função HTTP. Este teste verifica se a resposta esperada é retornada.
    • Http_trigger_should_return_string_from_member_data: Este teste usa atributos xUnit para fornecer dados de exemplo para a função HTTP.
    • Timer_should_log_message: Este teste cria uma instância de ListLogger e passa-a para uma função temporizadora. Depois que a função é executada, o log é verificado para certificar-se de que a mensagem esperada está presente.
  6. Para acessar as configurações do aplicativo em seus testes, você pode injetar uma IConfiguration implementação com valores de variáveis de ambiente simulados em sua função.

Etapa 3: Executar testes

Para executar os testes no Visual Studio, selecione Exibir>Gerenciador de Testes. No Gerenciador de Testes, selecione Executar>Executar Todos os Testes no Modo de Exibição.

Captura de tela do Visual Studio. O Test Explorer mostra que cinco testes foram aprovados. No Gerenciador de Soluções, os projetos Functions e Functions.Test são visíveis.

Etapa 4: Depurar testes

Para depurar os testes, defina um ponto de interrupção em um teste. No Test Explorer, selecione Executar>Depurar Última Execução.