Use dependency injection in .NET Azure Functions (Korzystanie z wstrzykiwania zależności w usłudze Azure Functions na platformie .NET)

Usługa Azure Functions obsługuje wzorzec projektowania oprogramowania iniekcji zależności (DI), który jest techniką umożliwiającą osiągnięcie inwersji kontroli (IoC) między klasami i ich zależnościami.

  • Wstrzykiwanie zależności w usłudze Azure Functions jest oparte na funkcjach iniekcji zależności platformy .NET Core. Zalecana jest znajomość wstrzykiwania zależności platformy .NET Core. Istnieją różnice w sposobie zastępowania zależności i odczytywania wartości konfiguracji za pomocą usługi Azure Functions w planie Zużycie.

  • Obsługa wstrzykiwania zależności rozpoczyna się od usługi Azure Functions 2.x.

  • Wzorce wstrzykiwania zależności różnią się w zależności od tego, czy funkcje języka C# działają w procesie , czy poza procesem.

Ważne

Wskazówki zawarte w tym artykule dotyczą tylko funkcji biblioteki klas języka C#, które są uruchamiane w trakcie procesu w środowisku uruchomieniowym. Ten niestandardowy model wstrzykiwania zależności nie ma zastosowania do funkcji izolowanych platformy .NET, co umożliwia uruchamianie funkcji platformy .NET poza procesem. Model izolowanego procesu roboczego platformy .NET opiera się na regularnych wzorcach wstrzykiwania zależności ASP.NET Core. Aby dowiedzieć się więcej, zobacz Wstrzykiwanie zależności w przewodniku po izolowanym procesie roboczym platformy .NET.

Wymagania wstępne

Aby można było użyć iniekcji zależności, należy zainstalować następujące pakiety NuGet:

Rejestrowanie usług

Aby zarejestrować usługi, utwórz metodę konfigurowania i dodawania IFunctionsHostBuilder składników do wystąpienia. Host usługi Azure Functions tworzy wystąpienie IFunctionsHostBuilder obiektu i przekazuje je bezpośrednio do metody .

Ostrzeżenie

W przypadku aplikacji funkcji działających w planach Zużycie lub Premium modyfikacje wartości konfiguracji używanych w wyzwalaczach mogą powodować błędy skalowania. Wszelkie zmiany tych właściwości przez FunctionsStartup klasę będą skutkować błędem uruchamiania aplikacji funkcji.

Wstrzykiwanie może prowadzić do nieoczekiwanego IConfiguration zachowania. Aby dowiedzieć się więcej na temat dodawania źródeł konfiguracji, zobacz Dostosowywanie źródeł konfiguracji.

Aby zarejestrować metodę, dodaj FunctionsStartup atrybut zestawu, który określa nazwę typu używaną podczas uruchamiania.

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

W tym przykładzie użyto pakietu Microsoft.Extensions.Http wymaganego do zarejestrowania się podczas uruchamiania HttpClient .

Zastrzeżenia

Seria kroków rejestracji uruchamianych przed i po uruchomieniu przetwarza klasę uruchamiania. Dlatego należy pamiętać o następujących elementach:

  • Klasa uruchamiania jest przeznaczona tylko do instalacji i rejestracji. Unikaj korzystania z usług zarejestrowanych podczas uruchamiania podczas procesu uruchamiania. Na przykład nie należy próbować rejestrować komunikatu w rejestratorze, który jest rejestrowany podczas uruchamiania. Ten punkt procesu rejestracji jest za wcześnie, aby usługi można było korzystać z nich. Po uruchomieniu Configure metody środowisko uruchomieniowe usługi Functions nadal rejestruje inne zależności, co może mieć wpływ na sposób działania usług.

  • Kontener wstrzykiwania zależności zawiera tylko jawnie zarejestrowane typy. Jedynymi usługami dostępnymi jako typy, które można wprowadzać, są skonfigurowane w metodzie Configure . W związku z tym typy specyficzne dla funkcji, takie jak BindingContext i ExecutionContext nie są dostępne podczas instalacji lub jako typy do wstrzykiwania.

  • Konfigurowanie uwierzytelniania ASP.NET nie jest obsługiwane. Host usługi Functions konfiguruje ASP.NET usług uwierzytelniania, aby prawidłowo uwidaczniać interfejsy API dla podstawowych operacji cyklu życia. Inne konfiguracje w klasie niestandardowej Startup mogą zastąpić tę konfigurację, powodując niezamierzone konsekwencje. Na przykład wywołanie builder.Services.AddAuthentication() może przerwać uwierzytelnianie między portalem a hostem, co prowadzi do komunikatów, takich jak środowisko uruchomieniowe usługi Azure Functions, jest niedostępne.

Używanie wstrzykiwanych zależności

Wstrzykiwanie konstruktora służy do udostępniania zależności w funkcji. Użycie iniekcji konstruktora wymaga, aby nie używać klas statycznych do wstrzykiwania usług ani klas funkcji.

W poniższym przykładzie pokazano, jak IMyService zależności i HttpClient są wstrzykiwane do funkcji wyzwalanej przez protokół 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.");
    }
}

W tym przykładzie użyto pakietu Microsoft.Extensions.Http wymaganego do zarejestrowania się podczas uruchamiania HttpClient .

Okresy istnienia usługi

Aplikacje usługi Azure Functions zapewniają te same okresy istnienia usługi co ASP.NET wstrzykiwanie zależności. W przypadku aplikacji usługi Functions różne okresy istnienia usługi zachowują się w następujący sposób:

  • Przejściowe: usługi przejściowe są tworzone po każdym rozwiązaniu usługi.
  • Zakres: okres istnienia usługi w zakresie jest zgodny z okresem wykonywania funkcji. Usługi o określonym zakresie są tworzone raz na wykonanie funkcji. Później żądania dotyczące tej usługi podczas wykonywania ponownie użyjemy istniejącego wystąpienia usługi.
  • Singleton: Okres istnienia pojedynczej usługi jest zgodny z okresem istnienia hosta i jest ponownie używany w ramach wykonywania funkcji w tym wystąpieniu. Usługi pojedynczego okresu istnienia są zalecane w przypadku połączeń i klientów, na przykład DocumentClient lub HttpClient wystąpień.

Wyświetl lub pobierz przykład różnych okresów istnienia usługi w usłudze GitHub.

Usługi rejestrowania

Jeśli potrzebujesz własnego dostawcy rejestrowania, zarejestruj typ niestandardowy jako wystąpienie ILoggerProviderprogramu , które jest dostępne za pośrednictwem pakietu NuGet Microsoft.Extensions.Logging.Abstractions .

Usługa Azure Functions automatycznie dodaje Szczegółowe informacje aplikacji.

Ostrzeżenie

  • Nie należy dodawać AddApplicationInsightsTelemetry() do kolekcji usług, która rejestruje usługi powodujące konflikt z usługami udostępnianymi przez środowisko.
  • Nie rejestruj się samodzielnie TelemetryConfiguration lub TelemetryClient jeśli używasz wbudowanej funkcji Szczegółowe informacje aplikacji. Jeśli musisz skonfigurować własne TelemetryClient wystąpienie, utwórz je za pośrednictwem wstrzyknięcia, jak pokazano TelemetryConfiguration w temacie Log custom telemetry in C# functions (Rejestrowanie niestandardowych danych telemetrycznych w funkcjach języka C#).

ILogger<T> i ILoggerFactory

Host wprowadza i ILogger<T>ILoggerFactory usługi do konstruktorów. Jednak domyślnie te nowe filtry rejestrowania są filtrowane z dzienników funkcji. Należy zmodyfikować plik, host.json aby wyrazić zgodę na dodatkowe filtry i kategorie.

W poniższym przykładzie pokazano, jak dodać element ILogger<HttpTrigger> z dziennikami, które są widoczne dla hosta.

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

        // ...
}

Poniższy przykładowy host.json plik dodaje filtr dziennika.

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

Aby uzyskać więcej informacji na temat poziomów dzienników, zobacz Konfigurowanie poziomów dziennika.

Usługi udostępniane przez aplikację funkcji

Host funkcji rejestruje wiele usług. Następujące usługi są bezpieczne do podjęcia jako zależność w aplikacji:

Typ usługi Okres istnienia opis
Microsoft.Extensions.Configuration.IConfiguration Pojedyncze Konfiguracja środowiska uruchomieniowego
Microsoft.Azure.WebJobs.Host.Executors.IHostIdProvider Pojedyncze Odpowiedzialny za podanie identyfikatora wystąpienia hosta

Jeśli istnieją inne usługi, z których chcesz korzystać, utwórz problem i zaproponuj je w usłudze GitHub.

Zastępowanie usług hosta

Zastępowanie usług udostępnianych przez hosta nie jest obecnie obsługiwane. Jeśli istnieją usługi, które chcesz zastąpić, utwórz problem i zaproponuj je w usłudze GitHub.

Praca z opcjami i ustawieniami

Wartości zdefiniowane w ustawieniach aplikacji są dostępne w wystąpieniu IConfiguration , co umożliwia odczytywanie wartości ustawień aplikacji w klasie uruchamiania.

Wartości z IConfiguration wystąpienia można wyodrębnić do typu niestandardowego. Kopiowanie wartości ustawień aplikacji do typu niestandardowego ułatwia testowanie usług przez wprowadzanie tych wartości. Ustawienia odczytywać wystąpienie konfiguracji musi być prostymi parami klucz/wartość. W przypadku funkcji uruchomionych w ramach planu Elastic Premium nazwy ustawień aplikacji mogą zawierać tylko litery, cyfry (0-9), kropki (), dwukropki (.:) i podkreślenia (_). Aby uzyskać więcej informacji, zobacz Zagadnienia dotyczące ustawień aplikacji.

Rozważmy następującą klasę zawierającą właściwość o nazwie spójną z ustawieniem aplikacji:

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

local.settings.json Plik, który może strukturę ustawienia niestandardowego w następujący sposób:

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

Z poziomu Startup.Configure metody można wyodrębnić wartości z IConfiguration wystąpienia do typu niestandardowego przy użyciu następującego kodu:

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

Wywoływanie Bind kopii wartości, które mają pasujące nazwy właściwości z konfiguracji do wystąpienia niestandardowego. Wystąpienie opcji jest teraz dostępne w kontenerze IoC do wstrzykiwania do funkcji.

Obiekt options jest wstrzykiwany do funkcji jako wystąpienie interfejsu ogólnego IOptions . Użyj właściwości , Value aby uzyskać dostęp do wartości znalezionych w konfiguracji.

using System;
using Microsoft.Extensions.Options;

public class HttpTrigger
{
    private readonly MyOptions _settings;

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

Aby uzyskać więcej informacji, zobacz Wzorzec opcji w programie ASP.NET Core.

Używanie wpisów tajnych użytkownika platformy ASP.NET Core

Podczas lokalnego opracowywania aplikacji ASP.NET Core udostępnia narzędzie Secret Manager, które umożliwia przechowywanie informacji tajnych poza katalogiem głównym projektu. Sprawia to, że mniej prawdopodobne jest, aby wpisy tajne zostały przypadkowo zatwierdzone do kontroli źródła. Narzędzia Azure Functions Core Tools (wersja 3.0.3233 lub nowsza) automatycznie odczytują wpisy tajne utworzone przez program ASP.NET Core Secret Manager.

Aby skonfigurować projekt usługi Azure Functions platformy .NET do używania wpisów tajnych użytkownika, uruchom następujące polecenie w katalogu głównym projektu.

dotnet user-secrets init

Następnie użyj polecenia , dotnet user-secrets set aby utworzyć lub zaktualizować wpisy tajne.

dotnet user-secrets set MySecret "my secret value"

Aby uzyskać dostęp do wartości wpisów tajnych użytkownika w kodzie aplikacji funkcji, użyj polecenia IConfiguration lub IOptions.

Dostosowywanie źródeł konfiguracji

Aby określić inne źródła konfiguracji, zastąpij metodę ConfigureAppConfiguration w klasie aplikacji StartUp funkcji.

Poniższy przykład dodaje wartości konfiguracji zarówno z podstawowych, jak i opcjonalnych plików ustawień aplikacji specyficznych dla środowiska.

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

Dodaj dostawców konfiguracji do ConfigurationBuilder właściwości IFunctionsConfigurationBuilder. Aby uzyskać więcej informacji na temat korzystania z dostawców konfiguracji, zobacz Configuration in ASP.NET Core (Konfiguracja w programie ASP.NET Core).

Element A FunctionsHostBuilderContext jest uzyskiwany z IFunctionsConfigurationBuilder.GetContext(). Użyj tego kontekstu, aby pobrać bieżącą nazwę środowiska i rozpoznać lokalizację plików konfiguracji w folderze aplikacji funkcji.

Domyślnie pliki konfiguracji, takie jak appsettings.json nie są automatycznie kopiowane do folderu wyjściowego aplikacji funkcji. .csproj Zaktualizuj plik, aby był zgodny z poniższym przykładem, aby upewnić się, że pliki są kopiowane.

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

Następne kroki

Aby uzyskać więcej informacji, zobacz następujące zasoby: