Použití injektáže závislostí ve službě Azure Functions pro .NET

Azure Functions podporuje model návrhu softwaru injektáž závislostí (DI), což je technika pro dosažení inverze řízení (IoC) mezi třídami a jejich závislostmi.

  • Injektáž závislostí ve službě Azure Functions je založená na funkcích injektáže závislostí .NET Core. Doporučuje se znalost injektáže závislostí .NET Core. Existují rozdíly v tom, jak přepíšete závislosti a jak se hodnoty konfigurace čtou ve službě Azure Functions v plánu Consumption.

  • Podpora injektáže závislostí začíná službou Azure Functions 2.x.

  • Vzory injektáže závislostí se liší v závislosti na tom, jestli vaše funkce jazyka C# běží v procesu nebo mimo proces.

Důležité

Pokyny v tomto článku platí jenom pro funkce knihovny tříd jazyka C#, které spouštějí proces s modulem runtime. Tento vlastní model injektáže závislostí se nevztahuje na izolované funkce .NET, které umožňují spouštět funkce .NET mimo proces. Model izolovaného pracovního procesu .NET spoléhá na běžné vzory injektáže závislostí ASP.NET Core. Další informace najdete v tématu Injektáž závislostí v průvodci izolovaným pracovním procesem .NET.

Požadavky

Před použitím injektáže závislostí musíte nainstalovat následující balíčky NuGet:

Registrace služeb

Pokud chcete registrovat služby, vytvořte metodu pro konfiguraci a přidání komponent do IFunctionsHostBuilder instance. Hostitel Azure Functions vytvoří instanci IFunctionsHostBuilder a předá ji přímo do vaší metody.

Upozorňující

U aplikací funkcí běžících v plánech Consumption nebo Premium můžou změny hodnot konfigurace použitých v triggerech způsobit chyby škálování. Všechny změny těchto vlastností podle FunctionsStartup třídy způsobí chybu spuštění aplikace funkcí.

IConfiguration Injektáž může vést k neočekávanému chování. Další informace o přidávání zdrojů konfigurace najdete v tématu Přizpůsobení zdrojů konfigurace.

Chcete-li zaregistrovat metodu FunctionsStartup , přidejte atribut sestavení, který určuje název typu použitý při spuštění.

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>();
    }
}

Tento příklad používá balíček Microsoft.Extensions.Http potřebný k registraci HttpClient při spuštění.

Upozornění

Řada kroků registrace se spouští před a po spuštění modulu runtime, zpracovává spouštěcí třídu. Proto mějte na paměti následující položky:

  • Spouštěcí třída je určena pouze pro nastavení a registraci. Vyhněte se používání služeb zaregistrovaných při spuštění během procesu spuštění. Nepokoušejte se například protokolovat zprávu v protokolovacím nástroji, který je zaregistrovaný při spuštění. Tento bod procesu registrace je příliš brzy, aby vaše služby byly k dispozici pro použití. Configure Po spuštění metody modul runtime Služby Functions nadále registruje další závislosti, které můžou ovlivnit fungování vašich služeb.

  • Kontejner injektáže závislostí obsahuje pouze explicitně registrované typy. Jediné služby, které jsou k dispozici jako injektovatelné typy, jsou to, co jsou nastavené v Configure metodě. V důsledku toho jsou typy specifické pro funkce podobné BindingContext a ExecutionContext nejsou během instalace nebo jako injektovatelné typy dostupné.

  • Konfigurace ověřování ASP.NET se nepodporuje. Hostitel služby Functions nakonfiguruje ASP.NET ověřovací služby tak, aby správně zpřístupnil rozhraní API pro základní operace životního cyklu. Jiné konfigurace ve vlastní Startup třídě mohou tuto konfiguraci přepsat, což způsobuje nezamýšlené důsledky. Volání builder.Services.AddAuthentication() může například přerušit ověřování mezi portálem a hostitelem, což vede k nedostupnosti zpráv, jako je modul runtime Azure Functions.

Použití vloženého závislostí

Injektáž konstruktoru slouží k zpřístupnění závislostí ve funkci. Použití injektáže konstruktoru vyžaduje, abyste pro vložené služby nebo třídy funkcí nepoužívejte statické třídy.

Následující ukázka ukazuje, jak IMyServiceHttpClient se závislosti vloží do funkce aktivované protokolem 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.");
    }
}

Tento příklad používá balíček Microsoft.Extensions.Http potřebný k registraci HttpClient při spuštění.

Životnost služeb

Aplikace Azure Functions poskytují stejnou dobu životnosti služeb jako injektáž závislostí ASP.NET. U aplikace Functions se různé životnosti služeb chovají takto:

  • Přechodné: Přechodné služby se vytvářejí při každém překladu služby.
  • Obor: Doba života služby v oboru odpovídá době provádění funkce. Služby s vymezeným oborem se vytvářejí jednou pro každé spuštění funkce. Později se na danou službu během provádění znovu použije existující instance služby.
  • Singleton: Životnost služby singleton odpovídá době životnosti hostitele a je opakovaně používána napříč prováděními funkcí v dané instanci. Služby s jednou životností se doporučují pro připojení a klienty, například DocumentClientHttpClient pro instance.

Prohlédněte si nebo stáhněte ukázku různých životností služeb na GitHubu.

Služby protokolování

Pokud potřebujete vlastního zprostředkovatele protokolování, zaregistrujte vlastní typ jako instanci ILoggerProvider, která je k dispozici prostřednictvím balíčku NuGet Microsoft.Extensions.Logging.Abstractions .

Služba Azure Functions automaticky přidá Přehledy aplikace.

Upozorňující

  • Nepřidávejte AddApplicationInsightsTelemetry() do kolekce služeb, která registruje služby, které jsou v konfliktu se službami poskytovanými prostředím.
  • Nezaregistrujte si vlastní TelemetryConfiguration nebo TelemetryClient pokud používáte předdefinované funkce Přehledy aplikace. Pokud potřebujete nakonfigurovat vlastní TelemetryClient instanci, vytvořte ji prostřednictvím vložené TelemetryConfiguration instance, jak je znázorněno v části Protokolování vlastní telemetrie ve funkcích jazyka C#.

ILogger<T> a ILoggerFactory

Hostitel vloží ILogger<T> služby ILoggerFactory do konstruktorů. Ve výchozím nastavení se ale tyto nové filtry protokolování odfiltrují z protokolů funkcí. Soubor je potřeba upravit host.json tak, aby se přihlásil k dalším filtrům a kategoriím.

Následující příklad ukazuje, jak přidat ILogger<HttpTrigger> s protokoly, které jsou vystaveny hostiteli.

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.");

        // ...
}

Následující ukázkový host.json soubor přidá filtr protokolu.

{
    "version": "2.0",
    "logging": {
        "applicationInsights": {
            "samplingSettings": {
                "isEnabled": true,
                "excludedTypes": "Request"
            }
        },
        "logLevel": {
            "MyNamespace.HttpTrigger": "Information"
        }
    }
}

Další informace o úrovních protokolů najdete v tématu Konfigurace úrovní protokolu.

Poskytované služby aplikace funkcí

Hostitel funkce registruje mnoho služeb. Následující služby jsou bezpečné, aby se ve vaší aplikaci vezmou jako závislost:

Typ služby Životnost Popis
Microsoft.Extensions.Configuration.IConfiguration Singleton Konfigurace modulu runtime
Microsoft.Azure.WebJobs.Host.Executors.IHostIdProvider Singleton Zodpovídá za poskytnutí ID instance hostitele.

Pokud existují další služby, na které chcete závislost využít, vytvořte problém a na GitHubu je navrhnete.

Přepsání hostitelských služeb

Přepsání služeb poskytovaných hostitelem se v současné době nepodporuje. Pokud existují služby, které chcete přepsat, vytvořte problém a na GitHubu je navrhnete.

Práce s možnostmi a nastavením

Hodnoty definované v nastavení aplikace jsou k dispozici v IConfiguration instanci, což umožňuje číst hodnoty nastavení aplikace ve spouštěcí třídě.

Hodnoty z IConfiguration instance můžete extrahovat do vlastního typu. Zkopírování hodnot nastavení aplikace do vlastního typu usnadňuje testování služeb tím, že tyto hodnoty vložíte. Nastavení čtení do instance konfigurace musí být jednoduché páry klíč/hodnota. Pro funkce spuštěné v plánu Elastic Premium můžou názvy nastavení aplikace obsahovat jenom písmena, číslice (0-9), tečky (.), dvojtečky (:) a podtržítka (_). Další informace najdete v tématu Důležité informace o nastavení aplikace.

Vezměte v úvahu následující třídu, která obsahuje vlastnost s názvem konzistentní s nastavením aplikace:

public class MyOptions
{
    public string MyCustomSetting { get; set; }
}

local.settings.json A soubor, který by mohl vlastní nastavení strukturovat takto:

{
  "IsEncrypted": false,
  "Values": {
    "MyOptions:MyCustomSetting": "Foobar"
  }
}

Startup.Configure Z této metody můžete extrahovat hodnoty z IConfiguration instance do vlastního typu pomocí následujícího kódu:

builder.Services.AddOptions<MyOptions>()
    .Configure<IConfiguration>((settings, configuration) =>
    {
        configuration.GetSection("MyOptions").Bind(settings);
    });

Volání Bind kopíruje hodnoty, které mají odpovídající názvy vlastností z konfigurace do vlastní instance. Instance možností je nyní k dispozici v kontejneru IoC pro vložení do funkce.

Objekt options se vloží do funkce jako instance obecného IOptions rozhraní. Value Pomocí vlastnosti získáte přístup k hodnotám nalezených v konfiguraci.

using System;
using Microsoft.Extensions.Options;

public class HttpTrigger
{
    private readonly MyOptions _settings;

    public HttpTrigger(IOptions<MyOptions> options)
    {
        _settings = options.Value;
    }
}

Další informace najdete v tématu Možnosti v ASP.NET Core.

Použití tajných kódů uživatele ASP.NET Core

Při místním vývoji aplikace poskytuje ASP.NET Core nástroj Secret Manager, který umožňuje ukládat tajné informace mimo kořen projektu. Je méně pravděpodobné, že se tajné kódy omylem potvrdí ke správě zdrojového kódu. Azure Functions Core Tools (verze 3.0.3233 nebo novější) automaticky čte tajné kódy vytvořené správcem tajných kódů ASP.NET Core Secret Manager.

Pokud chcete nakonfigurovat projekt .NET Azure Functions tak, aby používal tajné kódy uživatelů, spusťte v kořenovém adresáři projektu následující příkaz.

dotnet user-secrets init

Pak pomocí dotnet user-secrets set příkazu vytvořte nebo aktualizujte tajné kódy.

dotnet user-secrets set MySecret "my secret value"

Pokud chcete získat přístup k hodnotám tajných kódů uživatelů v kódu aplikace funkcí, použijte IConfiguration nebo IOptions.

Přizpůsobení zdrojů konfigurace

Pokud chcete zadat další zdroje konfigurace, přepište metodu ConfigureAppConfiguration ve třídě vaší aplikace StartUp funkcí.

Následující ukázka přidá konfigurační hodnoty ze základních i volitelných souborů nastavení aplikace specifické pro prostředí.

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)
    {
    }
}

Přidání zprostředkovatelů konfigurace do ConfigurationBuilder vlastnosti IFunctionsConfigurationBuilder. Další informace o používání zprostředkovatelů konfigurace najdete v tématu Konfigurace v ASP.NET Core.

A FunctionsHostBuilderContext je získán z IFunctionsConfigurationBuilder.GetContext(). Tento kontext použijte k načtení aktuálního názvu prostředí a překladu umístění konfiguračních souborů ve složce aplikace funkcí.

Ve výchozím nastavení se konfigurační soubory, jako appsettings.json jsou, automaticky nekopírují do výstupní složky aplikace funkcí. Aktualizujte .csproj soubor tak, aby odpovídal následující ukázce, aby se zajistilo, že se soubory zkopírují.

<None Update="appsettings.json">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>      
</None>
<None Update="appsettings.Development.json">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>

Další kroky

Další informace naleznete v následujících zdrojích: