Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Azure Functions unterstützt das Di-Softwaredesignmuster (Dependency Injection), bei dem es sich um eine Technik zum Erreichen von Inversion of Control (IoC) zwischen Klassen und deren Abhängigkeiten handelt.
Die Abhängigkeitsinjektion in Azure Functions basiert auf den .NET Core Dependency Injection-Features. Vertrautheit mit .NET Core Dependency Injection wird empfohlen. Es gibt Unterschiede bei der Außerkraftsetzung von Abhängigkeiten und wie Konfigurationswerte mit Azure-Funktionen im Verbrauchsplan gelesen werden.
Die Unterstützung für abhängigkeitsinjektion beginnt mit Azure Functions 2.x.
Abhängigkeitsinjektionsmuster unterscheiden sich je nachdem, ob Ihre C# -Funktionen im Prozess oder außerhalb des Prozesses ausgeführt werden.
Von Bedeutung
Die Anleitungen in diesem Artikel gelten nur für C#-Klassenbibliotheksfunktionen, die mit der Laufzeit ausgeführt werden. Dieses benutzerdefinierte Abhängigkeitseinfügungsmodell gilt nicht für isolierte .NET-Funktionen, mit denen Sie .NET-Funktionen außerhalb des Prozesses ausführen können. Das .NET Isolierte Arbeitsprozessmodell basiert auf normalen ASP.NET Core-Abhängigkeitsinjektionsmustern. Weitere Informationen finden Sie unter Dependency Injection im .NET-Handbuch für isolierte Arbeitsprozesse.
Voraussetzungen
Bevor Sie die Abhängigkeitseinfügung verwenden können, müssen Sie die folgenden NuGet-Pakete installieren:
Paketversion 1.0.28 oder höher von Microsoft.NET.Sdk.Functions
Microsoft.Extensions.DependencyInjection (derzeit nur Version 2.x oder höher unterstützt)
Registrieren von Diensten
Um Dienste zu registrieren, erstellen Sie eine Methode zum Konfigurieren und Hinzufügen von Komponenten zu einer IFunctionsHostBuilder
Instanz. Der Azure Functions-Host erstellt eine Instanz von IFunctionsHostBuilder
und übergibt sie direkt an Ihre Methode.
Warnung
Bei Funktions-Apps, die in den Plänen "Verbrauch" oder "Premium" ausgeführt werden, können Änderungen an konfigurationswerten, die in Triggern verwendet werden, zu Skalierungsfehlern führen. Alle Änderungen an diesen Eigenschaften durch die FunctionsStartup
Klasse führen zu einem Funktions-App-Startfehler.
IConfiguration
Die Injektion kann zu unerwartetem Verhalten führen. Weitere Informationen zum Hinzufügen von Konfigurationsquellen finden Sie unter Anpassen von Konfigurationsquellen.
Um die Methode zu registrieren, fügen Sie das FunctionsStartup
Assembly-Attribut hinzu, das den Typnamen angibt, der beim Start verwendet wird.
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>();
}
}
In diesem Beispiel wird das Microsoft.Extensions.Http-Paket verwendet, das erforderlich ist, um beim Start eine HttpClient
zu registrieren.
Vorbehalte
Eine Reihe von Registrierungsschritten wird vor und nach dem Verarbeiten der Startup-Klasse durch die Runtime ausgeführt. Beachten Sie daher die folgenden Elemente:
Die Startklasse ist nur für Setup und Registrierung vorgesehen. Vermeiden Sie die Verwendung von Diensten, die beim Start registriert sind, während des Startvorgangs. Versuchen Sie beispielsweise nicht, eine Nachricht in einem Logger zu protokollieren, der während des Starts registriert wird. Dieser Zeitpunkt des Registrierungsprozesses ist zu früh, damit Ihre Dienste zur Nutzung zur Verfügung stehen. Nachdem die
Configure
Methode ausgeführt wurde, registriert die Functions-Laufzeit weiterhin andere Abhängigkeiten, was sich darauf auswirken kann, wie Ihre Dienste funktionieren.Der Container zum Einfügen von Abhängigkeiten enthält nur explizit registrierte Typen. Die einzigen Dienste, die als injizierbare Typen verfügbar sind, sind die in der
Configure
Methode eingerichteten Dienste. Dies hat zur Folge, dass funktionsspezifische Typen wieBindingContext
undExecutionContext
während des Setups oder als injizierbare Typen nicht verfügbar sind.Das Konfigurieren ASP.NET Authentifizierung wird nicht unterstützt. Der Funktionenhost konfiguriert ASP.NET Authentifizierungsdienste, um APIs für kerne Lebenszyklusvorgänge ordnungsgemäß verfügbar zu machen. Andere Konfigurationen in einer benutzerdefinierten
Startup
Klasse können diese Konfiguration außer Kraft setzen, was zu unbeabsichtigten Folgen führt. Beispielsweise kann der Aufruf vonbuilder.Services.AddAuthentication()
die Authentifizierung zwischen dem Portal und dem Host unterbrechen, was zu Nachrichten führt, wie Azure Functions-Laufzeit ist nicht erreichbar.
Verwenden von eingefügten Abhängigkeiten
Die Konstruktorinjektion wird verwendet, um Ihre Abhängigkeiten in einer Funktion verfügbar zu machen. Die Verwendung der Konstruktoreinfügung erfordert, dass Sie keine statischen Klassen für eingefügte Dienste oder für Ihre Funktionsklassen verwenden.
Im folgenden Beispiel wird veranschaulicht, wie die Abhängigkeiten IMyService
und HttpClient
in eine durch HTTP ausgelöste Funktion eingefügt werden.
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.");
}
}
In diesem Beispiel wird das Microsoft.Extensions.Http-Paket verwendet, das erforderlich ist, um beim Start eine HttpClient
zu registrieren.
Dienstlebensdauer
Azure Functions-Apps bieten die gleichen Lebenszyklen von Diensten wie ASP.NET Dependency Injection. Bei einer Funktionen-App verhalten sich die verschiedenen Dienstlebensdauern wie folgt:
- Vorübergehend: Vorübergehende Dienste werden bei jeder Auflösung des Diensts erstellt.
- Bereichsbezogen: Die bereichsbezogene Lebensdauer eines Diensts entspricht der Ausführungslebensdauer einer Funktion. Bereichsbezogene Dienste werden einmal pro Funktionsausführung erstellt. Spätere Anforderungen für diesen Dienst während der Ausführung wiederverwenden die vorhandene Dienstinstanz.
-
Singleton: Die Singleton-Dienstlebensdauer entspricht der Hostlebensdauer und wird für diese Instanz über Funktionsausführungen hinweg wiederverwendet. Dienste mit Singleton-Lebensdauer werden für Verbindungen und Clients empfohlen, z. B. Instanzen von
DocumentClient
oderHttpClient
.
Anzeigen oder Herunterladen eines Beispiels verschiedener Dienstlebensdauern auf GitHub.
Protokollierungsdienste
Wenn Sie Ihren eigenen Protokollierungsanbieter benötigen, registrieren Sie einen benutzerdefinierten Typ als Instanz von ILoggerProvider
, der über das NuGet-Paket "Microsoft.Extensions.Logging.Abstractions NuGet" verfügbar ist.
Application Insights wird automatisch von Azure Functions hinzugefügt.
Warnung
- Fügen Sie
AddApplicationInsightsTelemetry()
nicht zur Dienste-Sammlung hinzu, da dadurch Dienste registriert werden, die mit den von der Umgebung bereitgestellten Diensten in Konflikt stehen. - Registrieren Sie nicht Ihre eigenen
TelemetryConfiguration
oderTelemetryClient
, wenn Sie die integrierte Application Insights-Funktion verwenden. Wenn Sie Ihre eigeneTelemetryClient
Instanz konfigurieren müssen, erstellen Sie eine über die eingefügteTelemetryConfiguration
Instanz, wie im Artikel "Benutzerdefinierte Telemetrie in C#-Funktionen protokollieren" beschrieben.
ILogger<T> und ILoggerFactory
Der Host fügt ILogger<T>
und ILoggerFactory
Dienste in Konstruktoren ein. Standardmäßig werden diese neuen Protokollierungsfilter jedoch aus den Funktionsprotokollen herausgefiltert. Sie müssen die host.json
Datei ändern, um zusätzliche Filter und Kategorien zu aktivieren.
Im folgenden Beispiel wird veranschaulicht, wie Sie ein ILogger<HttpTrigger>
mit Protokollen hinzufügen, die dem Host zur Verfügung gestellt werden.
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.");
// ...
}
Die folgende Beispieldatei host.json
fügt den Protokollfilter hinzu.
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
},
"logLevel": {
"MyNamespace.HttpTrigger": "Information"
}
}
}
Weitere Informationen zu Protokollebenen finden Sie unter Konfigurieren von Protokollebenen.
Dienste, die von Funktions-App bereitgestellt werden
Der Funktionshost registriert viele Dienste. Die folgenden Dienste sind sicher, als Abhängigkeit in Ihrer Anwendung zu übernehmen:
Diensttyp | Lebensdauer | BESCHREIBUNG |
---|---|---|
Microsoft.Extensions.Configuration.IConfiguration |
Singleton | Laufzeitkonfiguration |
Microsoft.Azure.WebJobs.Host.Executors.IHostIdProvider |
Singleton | Verantwortlich für die Bereitstellung der ID der Hostinstanz |
Wenn es andere Dienste gibt, von denen Sie eine Abhängigkeit annehmen möchten, erstellen Sie ein Problem, und schlagen Sie sie auf GitHub vor.
Überschreiben von Hostdiensten
Das Überschreiben der vom Host bereitgestellten Dienste wird derzeit nicht unterstützt. Wenn Dienste vorhanden sind, die Sie außer Kraft setzen möchten, erstellen Sie ein Problem, und schlagen Sie sie auf GitHub vor.
Arbeiten mit Optionen und Einstellungen
Werte, die in App-Einstellungen definiert sind, stehen in einer IConfiguration
Instanz zur Verfügung, mit der Sie App-Einstellungswerte in der Startklasse lesen können.
Sie können Werte aus der IConfiguration
Instanz in einen benutzerdefinierten Typ extrahieren. Das Kopieren der App-Einstellungswerte in einen benutzerdefinierten Typ erleichtert das Testen Ihrer Dienste, indem diese Werte injiziert werden können. Einstellungen, die in die Konfigurationsinstanz gelesen werden, müssen einfache Schlüssel-Wert-Paare sein. Bei Funktionen, die in einem Elastic Premium-Plan ausgeführt werden, können Anwendungseinstellungsnamen nur Buchstaben, Zahlen (0-9
), Punkte (), Doppelpunkte (.
) und Unterstriche (:
_
) enthalten. Weitere Informationen finden Sie unter Überlegungen zur App-Einstellung.
Berücksichtigen Sie die folgende Klasse, die eine Eigenschaft enthält, die mit einer App-Einstellung konsistent ist:
public class MyOptions
{
public string MyCustomSetting { get; set; }
}
Und eine local.settings.json
Datei, die die benutzerdefinierte Einstellung wie folgt strukturiert:
{
"IsEncrypted": false,
"Values": {
"MyOptions:MyCustomSetting": "Foobar"
}
}
Aus der Startup.Configure
Methode heraus können Sie Werte aus der IConfiguration
Instanz mithilfe des folgenden Codes in Ihren benutzerdefinierten Typ extrahieren:
builder.Services.AddOptions<MyOptions>()
.Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("MyOptions").Bind(settings);
});
Durch das Aufrufen von Bind
werden Werte, die übereinstimmende Eigenschaftsnamen in der Konfiguration haben, in die benutzerdefinierte Instanz kopiert. Die Optionsinstanz ist jetzt im IoC-Container verfügbar, um sie in eine Funktion einzufügen.
Das Optionsobjekt wird als Instanz der generischen IOptions
Schnittstelle in die Funktion eingefügt. Verwenden Sie die Value
Eigenschaft, um auf die In Ihrer Konfiguration gefundenen Werte zuzugreifen.
using System;
using Microsoft.Extensions.Options;
public class HttpTrigger
{
private readonly MyOptions _settings;
public HttpTrigger(IOptions<MyOptions> options)
{
_settings = options.Value;
}
}
Weitere Informationen finden Sie unter Optionsmuster in ASP.NET Core.
Verwenden von ASP.NET Core Benutzergeheimnissen
Wenn Sie Ihre App lokal entwickeln, stellt ASP.NET Core ein Tool für geheimen Manager bereit, mit dem Sie geheime Informationen außerhalb des Projektstamms speichern können. Dadurch sinkt die Wahrscheinlichkeit, dass Geheimnisse versehentlich in die Quellcodeverwaltung committet werden. Azure Functions Core Tools (Version 3.0.3233 oder höher) liest automatisch geheime Schlüssel, die vom ASP.NET Core Secret Manager erstellt wurden.
Um ein .NET Azure Functions-Projekt für die Verwendung von Benutzergeheimnissen zu konfigurieren, führen Sie den folgenden Befehl im Projektstamm aus.
dotnet user-secrets init
Verwenden Sie dann den dotnet user-secrets set
Befehl, um geheime Schlüssel zu erstellen oder zu aktualisieren.
dotnet user-secrets set MySecret "my secret value"
Um auf geheime Werte von Benutzern in Ihrem Funktions-App-Code zuzugreifen, verwenden IConfiguration
Oder IOptions
.
Anpassen von Konfigurationsquellen
Um andere Konfigurationsquellen anzugeben, überschreiben Sie die ConfigureAppConfiguration
Methode in der Klasse Ihrer Funktionsanwendung StartUp
.
Im folgenden Beispiel werden Konfigurationswerte aus Basis- und optionalen App-Einstellungsdateien hinzugefügt.
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)
{
}
}
Fügen Sie Konfigurationsanbieter zur ConfigurationBuilder
-Eigenschaft von IFunctionsConfigurationBuilder
hinzu. Weitere Informationen zur Verwendung von Konfigurationsanbietern finden Sie unter "Configuration in ASP.NET Core".
FunctionsHostBuilderContext
wird aus IFunctionsConfigurationBuilder.GetContext()
abgerufen. Verwenden Sie diesen Kontext, um den aktuellen Umgebungsnamen abzurufen und den Speicherort von Konfigurationsdateien in Ihrem Funktions-App-Ordner aufzulösen.
Standardmäßig werden Konfigurationsdateien wie appsettings.json
nicht automatisch in den Ausgabeordner der Funktions-App kopiert. Aktualisieren Sie Ihre .csproj
Datei so, dass sie mit dem folgenden Beispiel übereinstimmt, um sicherzustellen, dass die Dateien kopiert werden.
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
Nächste Schritte
Weitere Informationen finden Sie in den folgenden Ressourcen: