Sdílet prostřednictvím


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

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 injektování závislostí v .NET Core. Existují rozdíly v přepisování závislostí a čtení hodnot konfigurace ve službě Azure Functions v rámci plánu spotřeby.

  • 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.

Výstraha

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 registračních kroků se provádí před a po zpracování spouštěcí třídy v běhovém prostředí. 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í. Po spuštění metody Configure modul runtime 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 chybovým hlášením, jako je modul runtime Azure Functions je nedostupný.

Použijte vložené závislosti

Vkládání závislostí pomocí konstruktoru se používá pro zpřístupnění závislostí ve funkci. Použití injekce konstruktoru vyžaduje, abyste nepoužíváte statické třídy pro služby injektované nebo pro vaše funkční třídy.

Následující ukázka ukazuje, jak se závislosti IMyService a HttpClient injektují do funkce spuštěné pomocí protokolu 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 ASP.NET Dependency Injection. U aplikace Functions se různé životnosti služeb chovají takto:

  • Dočasné: Dočasné služby se vytvářejí při každém vyřešení služby.
  • Pode rozsahu: Doba životnosti služby v pode rozsahu odpovídá době životnosti vykonávání funkce. Služby s vymezeným oborem se vytvářejí jednou pro každé spuštění funkce. Následující žádosti o danou službu během jejího provádění znovu využívají existující instanci 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. Singleton služby se doporučují pro připojení a klienty, například DocumentClient nebo HttpClient 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 Application Insights se přidá automaticky službou Azure Functions.

Výstraha

  • 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 Application Insights. 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 vkládá služby ILogger<T> a ILoggerFactory do konstruktorů. Ve výchozím nastavení se ale tyto nové filtry protokolování odfiltrují z protokolů funkcí. Je třeba upravit soubor host.json, abyste zapnuli další filtry a kategorie.

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.

Služby poskytované aplikací funkcí

Hostitel funkce registruje mnoho služeb. Následující služby jsou bezpečné pro použití jako závislost ve vaší aplikaci.

Typ služby Životnost Popis
Microsoft.Extensions.Configuration.IConfiguration Unikát Konfigurace modulu runtime
Microsoft.Azure.WebJobs.Host.Executors.IHostIdProvider Unikát 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řekonání služeb hostitele

Nahrazení 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 učiníte injektovatelnými. Nastavení nač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 tajnosti omylem zanesou do systému správy verzí. 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 upřesnit další zdroje konfigurace, přepište metodu ConfigureAppConfiguration ve třídě StartUp ve vaší funkční aplikaci.

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řidejte zprostředkovatele konfigurace do vlastnosti ConfigurationBuilder objektu 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 určení umístění konfiguračních souborů ve vaší složce aplikace funkcí.

Ve výchozím nastavení se konfigurační soubory, jako například appsettings.json, 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 najdete v následujících zdrojích informací: