Függőséginjektálás használata a .NET Azure Functionsben
Az Azure Functions támogatja a függőséginjektálási (DI) szoftvertervezési mintát, amely az osztályok és függőségeik közötti vezérlési inverzió (IoC) megvalósításának technikája.
Az Azure Functions függőséginjektálása a .NET Core függőséginjektálási funkcióira épül. A .NET Core-függőséginjektálás ismerete ajánlott. A függőségek felülbírálása és a konfigurációs értékek olvasása az Azure Functionsben a használatalapú csomagban eltérő.
A függőséginjektálás támogatása az Azure Functions 2.x-zel kezdődik.
A függőséginjektálási minták attól függően különböznek, hogy a C#-függvények folyamatban vagy folyamaton kívül futnak-e.
Fontos
A cikkben található útmutatás csak a futtatókörnyezettel folyamatban futó C# osztálytárfüggvényekre vonatkozik. Ez az egyéni függőséginjektálási modell nem vonatkozik a .NET izolált függvényekre, ami lehetővé teszi a .NET-függvények folyamaton kívüli futtatását. A .NET izolált feldolgozói folyamatmodell a szokásos ASP.NET Core-függőséginjektálási mintákra támaszkodik. További információ: Függőséginjektálás a .NET izolált feldolgozói folyamat útmutatójában.
A függőséginjektálás használata előtt telepítenie kell a következő NuGet-csomagokat:
Microsoft.NET.Sdk.Functions csomag 1.0.28-es vagy újabb verzió
Microsoft.Extensions.DependencyInjection (jelenleg csak a 2.x vagy újabb verzió támogatott)
A szolgáltatások regisztrálásához hozzon létre egy metódust, amely konfigurálja és hozzáadja az összetevőket egy IFunctionsHostBuilder
példányhoz. Az Azure Functions-gazdagép létrehoz egy példányt IFunctionsHostBuilder
, és közvetlenül a metódusba továbbítja azt.
Figyelmeztetés
A Használat vagy Prémium csomagban futó függvényalkalmazások esetében az eseményindítókban használt konfigurációs értékek módosítása skálázási hibákat okozhat. Ha az osztály módosítja ezeket a FunctionsStartup
tulajdonságokat, az egy függvényalkalmazás indítási hibáját eredményezi.
Az injekció beadása IConfiguration
váratlan viselkedéshez vezethet. A konfigurációs források hozzáadásáról további információt a konfigurációs források testreszabása című témakörben talál.
A metódus regisztrálásához adja hozzá az FunctionsStartup
indításkor használt típusnevet meghatározó szerelvényattribútumot.
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>();
}
}
Ez a példa a Microsoft.Extensions.Http csomagot használja, amely az indításkor történő regisztrációhoz HttpClient
szükséges.
A futtatókörnyezet előtt és után futtatott regisztrációs lépések sorozata feldolgozza az indítási osztályt. Ezért tartsa szem előtt a következő elemeket:
Az indítási osztály csak a beállításra és a regisztrációra szolgál. Kerülje az indításkor regisztrált szolgáltatások használatát az indítási folyamat során. Például ne próbáljon meg naplózni egy üzenetet egy olyan naplózóban, amely az indítás során regisztrálva van. A regisztrációs folyamat ezen pontja még túl korai ahhoz, hogy a szolgáltatások használatra elérhetők legyenek. A metódus futtatása után a
Configure
Functions-futtatókörnyezet továbbra is regisztrál más függőségeket, amelyek hatással lehetnek a szolgáltatások működésére.A függőséginjektálási tároló csak kifejezetten regisztrált típusokat tartalmaz. A metódusban
Configure
csak injektálható típusokként elérhető szolgáltatások érhetők el. Ennek eredményeképpen a függvényspecifikus típusok a beállítás során vagy injektálható típusokként nemBindingContext
ExecutionContext
érhetők el.A ASP.NET hitelesítés konfigurálása nem támogatott. A Functions-gazdagép úgy konfigurálja ASP.NET hitelesítési szolgáltatásokat, hogy megfelelően tegye elérhetővé az API-kat az alapvető életciklus-műveletekhez. Az egyéni
Startup
osztály más konfigurációi felülbírálhatják ezt a konfigurációt, ami nem kívánt következményekkel jár. A hívásbuilder.Services.AddAuthentication()
például megszakíthatja a hitelesítést a portál és a gazdagép között, ami olyan üzenetekhez vezet, mint az Azure Functions-futtatókörnyezet, nem érhető el.
Konstruktorinjektálással elérhetővé teheti függőségeit egy függvényben. A konstruktorinjektálás használatához nem kell statikus osztályokat használni az injektált szolgáltatásokhoz vagy a függvényosztályokhoz.
Az alábbi minta bemutatja, hogy a rendszer hogyan szúrja be a IMyService
HttpClient
függőségeket egy HTTP által aktivált függvénybe.
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.");
}
}
Ez a példa a Microsoft.Extensions.Http csomagot használja, amely az indításkor történő regisztrációhoz HttpClient
szükséges.
Az Azure Functions-alkalmazások ugyanazokat a szolgáltatási élettartamokat biztosítják, mint ASP.NET függőséginjektálás. A Functions-alkalmazások esetében a különböző szolgáltatási élettartamok a következőképpen viselkednek:
- Átmeneti: Az átmeneti szolgáltatások a szolgáltatás minden felbontása után jönnek létre.
- Hatókör: A hatókörön belüli szolgáltatás élettartama megegyezik a függvény végrehajtási élettartamával. A hatókörön belüli szolgáltatások függvényvégrehajtásonként egyszer jönnek létre. A szolgáltatásra vonatkozó későbbi kérések a végrehajtás során újra felhasználják a meglévő szolgáltatáspéldányt.
- Singleton: Az egyszeri szolgáltatás élettartama megegyezik a gazdagép élettartamával, és az adott példányon lévő függvényvégrehajtások során újra felhasználja. Az egyszeri élettartamú szolgáltatások ajánlottak kapcsolatokhoz és ügyfelekhez, például
DocumentClient
példányokhozHttpClient
.
A GitHubon megtekintheti vagy letöltheti a különböző szolgáltatási élettartamok mintáját .
Ha saját naplózási szolgáltatóra van szüksége, regisztráljon egy egyéni típust példányként ILoggerProvider
, amely a Microsoft.Extensions.Logging.Abstractions NuGet csomagon keresztül érhető el.
Az Azure Functions automatikusan hozzáadja az alkalmazás Elemzések.
Figyelmeztetés
- Ne vegyen fel
AddApplicationInsightsTelemetry()
a szolgáltatásgyűjteménybe, amely a környezet által biztosított szolgáltatásokkal ütköző szolgáltatásokat regisztrálja. - Ne regisztrálja a sajátját
TelemetryConfiguration
, vagyTelemetryClient
ha a beépített Alkalmazás Elemzések funkciót használja. Ha sajátTelemetryClient
példányt kell konfigurálnia, hozzon létre egyet az injektáltTelemetryConfiguration
adatokon keresztül, ahogyan az a C#-függvények Egyéni napló telemetriai adataiban is látható.
A gazdagép konstruktorokba ILogger<T>
injektál és ILoggerFactory
szolgáltatásokat nyújt. Alapértelmezés szerint azonban ezek az új naplózási szűrők ki vannak szűrve a függvénynaplókból. Módosítania kell a fájlt, host.json
hogy további szűrőket és kategóriákat válasszon.
Az alábbi példa bemutatja, hogyan vehet fel olyan ILogger<HttpTrigger>
naplókat, amelyek a gazdagép számára vannak közzétéve.
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.");
// ...
}
Az alábbi példafájl host.json
hozzáadja a naplószűrőt.
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
},
"logLevel": {
"MyNamespace.HttpTrigger": "Information"
}
}
}
További információ a naplószintekről: Naplószintek konfigurálása.
A függvény gazdagépe számos szolgáltatást regisztrál. Az alábbi szolgáltatások biztonságosan használhatók függőségként az alkalmazásban:
Szolgáltatás típusa | Életre | Leírás |
---|---|---|
Microsoft.Extensions.Configuration.IConfiguration |
Egyedülálló | Futtatókörnyezet konfigurálása |
Microsoft.Azure.WebJobs.Host.Executors.IHostIdProvider |
Egyedülálló | A gazdagéppéldány azonosítójának megadásáért felelős |
Ha más szolgáltatásoktól szeretne függőséget vállalni, hozzon létre egy problémát, és javasolja őket a GitHubon.
A gazdagép által biztosított felülírási szolgáltatások jelenleg nem támogatottak. Ha vannak olyan szolgáltatások, amelyeket felül szeretne bírálni, hozzon létre egy problémát, és javasolja őket a GitHubon.
Az alkalmazásbeállításokban definiált értékek elérhetők egy IConfiguration
példányban, amely lehetővé teszi az alkalmazásbeállítások értékeinek olvasását az indítási osztályban.
A példányból IConfiguration
egyéni típusba nyerhet ki értékeket. Az alkalmazásbeállítások értékeinek egyéni típusba másolása megkönnyíti a szolgáltatások tesztelését azáltal, hogy ezeket az értékeket injektálhatóvá teszi. Gépház konfigurációs példányba való beolvasásnak egyszerű kulcs-érték pároknak kell lennie. Az Elastic Premium-csomagban futó függvények esetében az alkalmazásbeállítások nevei csak betűket, számokat (0-9
), pontokat (.
), kettőspontokat (:
) és aláhúzásjeleket (_
) tartalmazhatnak. További információ: Alkalmazásbeállítási szempontok.
Vegye figyelembe a következő osztályt, amely egy alkalmazásbeállítással konzisztens nevű tulajdonságot tartalmaz:
public class MyOptions
{
public string MyCustomSetting { get; set; }
}
És egy local.settings.json
fájl, amely az egyéni beállítást az alábbiak szerint strukturálhatja:
{
"IsEncrypted": false,
"Values": {
"MyOptions:MyCustomSetting": "Foobar"
}
}
A metóduson belül az Startup.Configure
alábbi kóddal kinyerheti a IConfiguration
példány értékeit az egyéni típusba:
builder.Services.AddOptions<MyOptions>()
.Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("MyOptions").Bind(settings);
});
A hívás Bind
olyan értékeket másol, amelyek tulajdonságnevei megegyeznek a konfigurációból az egyéni példányba. A beállításpéldány mostantól elérhető az IoC-tárolóban egy függvénybe való injektálásához.
A beállításobjektumot a rendszer az általános IOptions
felület példányaként injektálja a függvénybe. Value
A tulajdonság használatával elérheti a konfigurációban található értékeket.
using System;
using Microsoft.Extensions.Options;
public class HttpTrigger
{
private readonly MyOptions _settings;
public HttpTrigger(IOptions<MyOptions> options)
{
_settings = options.Value;
}
}
További információ: Beállítások minta a ASP.NET Core-ban.
Amikor helyileg fejleszti az alkalmazást, a ASP.NET Core egy Secret Manager-eszközt biztosít, amellyel titkos információkat tárolhat a projekt gyökerén kívül. Így kevésbé valószínű, hogy a titkos kulcsok véletlenül a forráskezelésre vannak kötelezve. Az Azure Functions Core Tools (3.0.3233-es vagy újabb verzió) automatikusan beolvassa a ASP.NET Core Secret Manager által létrehozott titkos kódokat.
Ha egy .NET Azure Functions-projektet felhasználói titkos kódok használatára szeretne konfigurálni, futtassa a következő parancsot a projekt gyökérkönyvtárában.
dotnet user-secrets init
Ezután a dotnet user-secrets set
paranccsal hozzon létre vagy frissítse a titkos kulcsokat.
dotnet user-secrets set MySecret "my secret value"
A függvényalkalmazás kódjában lévő felhasználói titkos kódok értékeinek eléréséhez használja IConfiguration
vagy IOptions
.
Más konfigurációs források megadásához felülbírálja a ConfigureAppConfiguration
függvényalkalmazás StartUp
osztályában található metódust.
Az alábbi minta konfigurációs értékeket ad hozzá az alap- és az opcionális környezetspecifikus alkalmazásbeállítás-fájlokból is.
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)
{
}
}
Konfigurációs szolgáltatók hozzáadása a ConfigurationBuilder
tulajdonsághoz IFunctionsConfigurationBuilder
. További információ a konfigurációszolgáltatók használatáról: Konfiguráció a ASP.NET Core-ban.
Az A-t FunctionsHostBuilderContext
a .IFunctionsConfigurationBuilder.GetContext()
Ezzel a környezettel lekérheti az aktuális környezetnevet, és feloldhatja a konfigurációs fájlok helyét a függvényalkalmazás mappájában.
Alapértelmezés szerint a konfigurációs fájlok, például appsettings.json
a rendszer nem másolja automatikusan a függvényalkalmazás kimeneti mappájába. Frissítse a fájlt úgy .csproj
, hogy az megfeleljen a következő mintának, és győződjön meg arról, hogy a fájlok másolása meg van győződve.
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
További információkat találhat az alábbi forrásokban: