Använda beroendeinmatning i .NET Azure Functions
Azure Functions stöder designmönstret för di-programvara (dependency injection), vilket är en teknik för att uppnå IoC (Inversion of Control) mellan klasser och deras beroenden.
Beroendeinjektion i Azure Functions bygger på funktionerna i .NET Core Dependency Injection. Vi rekommenderar att du är bekant med .NET Core-beroendeinjektion. Det finns skillnader i hur du åsidosätter beroenden och hur konfigurationsvärden läses Azure Functions i förbrukningsplanen.
Stöd för beroendeinjektion börjar med Azure Functions 2.x.
Beroendeinjektionsmönster varierar beroende på om dina C#-funktioner körs i process eller inte.
Viktigt
Vägledningen i den här artikeln gäller endast för C#-klassbiblioteksfunktioner, som körs i processen med körningen. Den här anpassade beroendeinjektionsmodellen gäller inte för isolerade .NET-funktioner,som gör att du kan köra .NET 5.0-funktioner utanför processen. Den isolerade .NET-processmodellen förlitar sig på ASP.NET Core mönster för beroenden. Mer information finns i Dependency injection (Beroendeinjektion) i guiden för isolerad .NET-process.
Förutsättningar
Innan du kan använda beroendeinjektion måste du installera följande NuGet-paket:
Microsoft .NET.Sdk.Functions-paketversion 1.0.28 eller senare
Microsoft.Extensions.DependencyInjection (för närvarande stöds endast version 3.x och tidigare)
Registrera tjänster
Om du vill registrera tjänster skapar du en metod för att konfigurera och lägga till komponenter i en IFunctionsHostBuilder instans. Den Azure Functions värden skapar en instans IFunctionsHostBuilder av och skickar den direkt till din -metod.
Registrera metoden genom att lägga till FunctionsStartup sammansättningsattributet som anger det typnamn som användes vid start.
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>();
}
}
}
I det här exemplet används det Microsoft.Extensions.Http-paket som krävs för att registrera HttpClient en vid start.
Varningar
En serie registreringssteg körs före och efter körningen bearbetar startklassen. Tänk därför på följande:
Startklassen är endast avsedd för installation och registrering. Undvik att använda tjänster som registrerats vid start under startprocessen. Försök till exempel inte att logga ett meddelande i en loggare som registreras under start. Den här punkten i registreringsprocessen är för tidig för att dina tjänster ska vara tillgängliga för användning. När
Configuremetoden har körts fortsätter Functions-körningen att registrera ytterligare beroenden, vilket kan påverka hur dina tjänster fungerar.Containern för beroendeinjektion innehåller endast explicit registrerade typer. De enda tjänster som är tillgängliga som injicerbara typer är de som konfigureras i
Configuremetoden . Därför är Functions-specifika typer som och inte tillgängliga underBindingContextExecutionContextinstallationen eller som injicerbara typer.
Använda inmatade beroenden
Konstruktorinjektion används för att göra dina beroenden tillgängliga i en funktion. Användningen av konstruktorinjektion kräver att du inte använder statiska klasser för inmatade tjänster eller för dina funktionsklasser.
Följande exempel visar hur beroendena IMyService och HttpClient matas in i en HTTP-utlöst funktion.
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.");
}
}
}
I det här exemplet används det Microsoft.Extensions.Http-paket som krävs för att registrera HttpClient en vid start.
Tjänstens livslängd
Azure Functions-appar ger samma livslängd för tjänsten som ASP.NET Dependency Injection. För en Functions-app fungerar de olika tjänstlivslängderna på följande sätt:
- Tillfälliga: Tillfälliga tjänster skapas vid varje lösning av tjänsten.
- Begränsad: Den begränsade livslängden för tjänsten matchar en funktionskörningslivslängd. Begränsade tjänster skapas en gång per funktionskörning. Senare begäranden för tjänsten under körningen återanvänder den befintliga tjänstinstansen.
- Singleton: Singleton-tjänstens livslängd matchar värdlivslängden och återanvänds vid funktionskörningar på den instansen. Singleton-livslängdstjänster rekommenderas för anslutningar och klienter,
DocumentClienttill exempelHttpClientinstanser.
Visa eller ladda ned ett exempel på olika livslängder för GitHub.
Loggningstjänster
Om du behöver en egen loggningsprovider registrerar du en anpassad typ som en instans av , som är tillgänglig via ILoggerProvider NuGet-paketet Microsoft.Extensions.Logging.Abstractions.
Program Insights läggs till av Azure Functions automatiskt.
Varning
- Lägg inte till
AddApplicationInsightsTelemetry()i tjänstesamlingen, som registrerar tjänster som står i konflikt med tjänster som tillhandahålls av miljön. - Registrera inte din egen
TelemetryConfigurationeller om du använder deTelemetryClientinbyggda funktionerna för Insights programhantering. Om du behöver konfigurera din egen instans skapar du en via den som matas in enligt loggningsanpassadTelemetryClientTelemetryConfigurationtelemetri i C#-funktioner.
ILogger <T> och ILoggerFactory
Värden matar in - ILogger<T> och ILoggerFactory -tjänster i konstruktorer. Som standard filtreras dessa nya loggningsfilter dock bort från funktionsloggarna. Du måste ändra filen host.json för att välja ytterligare filter och kategorier.
Följande exempel visar hur du lägger till en ILogger<HttpTrigger> med loggar som exponeras för värden.
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.");
// ...
}
}
Följande exempelfil host.json lägger till loggfiltret.
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
},
"logLevel": {
"MyNamespace.HttpTrigger": "Information"
}
}
}
Mer information om loggnivåer finns i Konfigurera loggnivåer.
Tjänster som tillhandahålls av funktionsappen
Funktionsvärden registrerar många tjänster. Följande tjänster är säkra att ta som ett beroende i ditt program:
| Typ av tjänst | Livstid | Description |
|---|---|---|
Microsoft.Extensions.Configuration.IConfiguration |
Singleton | Körningskonfiguration |
Microsoft.Azure.WebJobs.Host.Executors.IHostIdProvider |
Singleton | Ansvarar för att ange värdinstansens ID |
Om det finns andra tjänster som du vill ha ett beroende på skapar du ett ärende och föreslår dem GitHub.
Åsidosätta värdtjänster
Åsidosättning av tjänster som tillhandahålls av värden stöds inte för närvarande. Om det finns tjänster som du vill åsidosätta skapar du ett ärende och föreslår dem GitHub.
Arbeta med alternativ och inställningar
Värden som definierats i appinställningarna är tillgängliga IConfiguration i en instans, vilket gör att du kan läsa appinställningsvärden i startklassen.
Du kan extrahera värden från IConfiguration instansen till en anpassad typ. Genom att kopiera appinställningsvärdena till en anpassad typ kan du enkelt testa dina tjänster genom att göra dessa värden injicerbara. Inställningar som läses in i konfigurationsinstansen måste vara enkla nyckel/värde-par.
Tänk på följande klass som innehåller en egenskap med namnet consistent with an app setting (konsekvent med en appinställning):
public class MyOptions
{
public string MyCustomSetting { get; set; }
}
Och en local.settings.json fil som kan strukturera den anpassade inställningen på följande sätt:
{
"IsEncrypted": false,
"Values": {
"MyOptions:MyCustomSetting": "Foobar"
}
}
Inifrån metoden Startup.Configure kan du extrahera värden från IConfiguration instansen till din anpassade typ med hjälp av följande kod:
builder.Services.AddOptions<MyOptions>()
.Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("MyOptions").Bind(settings);
});
Anrop Bind kopierar värden som har matchande egenskapsnamn från konfigurationen till den anpassade instansen. Alternativinstansen är nu tillgänglig i IoC-containern för att mata in den i en funktion.
Options-objektet matas in i funktionen som en instans av det allmänna IOptions gränssnittet. Använd egenskapen Value för att komma åt värdena som finns i konfigurationen.
using System;
using Microsoft.Extensions.Options;
public class HttpTrigger
{
private readonly MyOptions _settings;
public HttpTrigger(IOptions<MyOptions> options)
{
_settings = options.Value;
}
}
Se Alternativmönster i ASP.NET Core mer information om hur du arbetar med alternativ.
Använda ASP.NET Core användarhemligheter
När du utvecklar lokalt ASP.NET Core ett Secret Manager-verktyg som gör att du kan lagra hemlig information utanför projektroten. Det gör det mindre troligt att hemligheter av misstag har utförts i källkontroll. Azure Functions Core Tools (version 3.0.3233 eller senare) läser automatiskt hemligheter som skapats av ASP.NET Core Secret Manager.
Om du vill konfigurera ett .NET Azure Functions-projekt att använda användarhemligheter kör du följande kommando i projektroten.
dotnet user-secrets init
Använd sedan kommandot dotnet user-secrets set för att skapa eller uppdatera hemligheter.
dotnet user-secrets set MySecret "my secret value"
Om du vill komma åt värden för användarhemligheter i funktionsappens kod använder IConfiguration du eller IOptions .
Anpassa konfigurationskällor
Anteckning
Anpassning av konfigurationskälla är tillgänglig från Azure Functions värdversionerna 2.0.14192.0 och 3.0.14191.0.
Om du vill ange ytterligare konfigurationskällor ConfigureAppConfiguration åsidosätter du metoden i funktionsappens StartUp -klass.
Följande exempel lägger till konfigurationsvärden från en bas och en valfri miljöspecifik appinställningsfil.
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();
}
}
}
Lägg till konfigurationsproviders ConfigurationBuilder i egenskapen för IFunctionsConfigurationBuilder . Mer information om hur du använder konfigurationsproviders finns i Konfiguration i ASP.NET Core.
En FunctionsHostBuilderContext hämtas från IFunctionsConfigurationBuilder.GetContext() . Använd den här kontexten för att hämta det aktuella miljönamnet och matcha platsen för konfigurationsfilerna i mappen för funktionsappen.
Som standard kopieras inte konfigurationsfiler som appsettings.json automatiskt till funktionsappens utdatamapp. Uppdatera .csproj-filen så att den matchar följande exempel för att säkerställa att filerna kopieras.
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
Viktigt
För funktionsappar som körs i förbruknings- eller Premium kan ändringar av konfigurationsvärden som används i utlösare orsaka skalningsfel. Om de här egenskaperna ändras av klassen FunctionsStartup resulterar det i ett fel vid start av funktionsappen.
Nästa steg
Mer information finns i följande resurser: