Azure Functions 支援相依性插入 (DI) 軟體設計模式,這是在類別與其相依性之間實現 控制反轉 (IoC) 的技術。
Azure Functions 中的相依性插入是以 .NET Core 相依性插入功能為基礎所建置。 建議熟悉 .NET Core 依賴注入。 在消耗性方案中,您覆寫相依性以及使用 Azure Functions 讀取組態值的方式有所不同。
相依性插入的支援從 Azure Functions 2.x 開始。
這很重要
本文中的指引僅適用於在同進程中使用運行時間的 C# 類別庫函數。 此自定義相依性插入模型不適用於 .NET 隔離函式,可讓您跨進程執行 .NET 函式。 .NET 隔離工作處理程序模型依賴一般的 ASP.NET Core 相依性注入模式。 若要深入瞭解,請參閱 .NET 隔離工作者進程指南中的 相依注入。
先決條件
您必須先安裝下列 NuGet 套件,才能使用相依性插入:
Microsoft.NET.Sdk.Functions 套件 1.0.28 版或更新版本
Microsoft.Extensions.DependencyInjection (目前僅支援 2.x 版或更新版本)
註冊服務
若要註冊服務,請建立方法來設定和新增元件至 IFunctionsHostBuilder
實例。 Azure Functions 主機會建立IFunctionsHostBuilder
的實例,並將它直接傳遞至您的方法。
警告
針對在消耗或高階方案中執行的函式應用程式,修改觸發程式中使用的組態值可能會導致調整規模錯誤。 類別 FunctionsStartup
對這些屬性所做的任何變更都會導致函式應用程式啟動錯誤。
插入 IConfiguration
可能會導致非預期的行為。 若要深入瞭解如何新增組態來源,請參閱 自定義組態來源。
若要註冊 方法,請新增 FunctionsStartup
元件屬性,以指定啟動期間所使用的類型名稱。
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>();
}
}
此範例會使用在啟動時註冊所需的 HttpClient
套件。
警示
一系列註冊步驟會在運行時間處理啟動類別之前和之後執行。 因此,請記住下列事項:
啟動類別僅適用於安裝和註冊。 避免在啟動程式期間使用在啟動時註冊的服務。 例如,請勿嘗試在啟動期間註冊的記錄器中記錄訊息。 在註冊流程的這個階段,您的服務仍然無法使用。 執行
Configure
方法之後,Functions 運行時間會繼續註冊其他相依性,這可能會影響服務的運作方式。相依性插入容器只會保留明確註冊的類型。 唯一可作為可插入型別的服務是 方法中
Configure
設定的服務。 因此,函式專屬的類型,例如BindingContext
和ExecutionContext
,在安裝期間或作為可注入類型時均無法使用。不支援設定 ASP.NET 驗證。 Functions 主機會設定 ASP.NET 驗證服務,以正確公開核心生命周期作業的 API。 自定義
Startup
類別中的其他組態可以覆寫此組態,造成非預期的結果。 例如,呼叫builder.Services.AddAuthentication()
可能會中斷入口網站與主機之間的驗證,導致出現 Azure Functions 執行環境無法連線 等訊息。
使用依賴注入
建構子注入可使您的相依性在函式中可用。 使用建構函式插入時,您不需要針對插入的服務或函式類別使用靜態類別。
下列範例示範如何將 IMyService
和 HttpClient
相依性插入 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.");
}
}
此範例會使用在啟動時註冊所需的 HttpClient
套件。
服務生命週期
Azure Functions 應用程式提供與 ASP.NET 依賴注入 相同的服務存留期。 針對 Functions 應用程式,不同的服務存留期的行為如下:
- 暫時性(Transient):暫時性服務會在每次解析請求時建立。
- 範圍:限定範圍服務存留期符合函式執行存留期。 每次函式執行時會建立一次限定範圍的服務。 執行時稍後對該服務的請求將重複使用現有的服務實例。
-
Singleton:單一服務存留期符合主機存留期,並可在該實例上的函式執行之間重複使用。 建議針對連線和用戶端使用單一存留期服務,例如
DocumentClient
或HttpClient
實例。
檢視或下載 GitHub 上 不同服務存留期的範例 。
記錄服務
如果您需要自己的記錄提供者,請將自訂型別註冊為 ILoggerProvider
的實例,該實例可透過 Microsoft.Extensions.Logging.Abstractions NuGet 套件取得。
Azure Functions 會自動新增 Application Insights。
警告
- 請勿新增
AddApplicationInsightsTelemetry()
至服務集合,這會註冊與環境所提供的服務衝突的服務。 - 如果您使用內建的 Application Insights 功能,請勿自行註冊
TelemetryConfiguration
或TelemetryClient
。 如果您需要設定自己的TelemetryClient
實例,請透過插入TelemetryConfiguration
建立實例,如 C# 函式中的記錄自定義遙測所示。
ILogger<T> 和 ILoggerFactory
主機會將 ILogger<T>
和 ILoggerFactory
服務插入建構函式。 不過,根據預設,這些新的記錄篩選器會被排除在函式記錄之外。 您必須修改 host.json
檔案,以選擇加入額外的篩選和類別。
下列範例示範如何使用公開至主機的記錄來新增 ILogger<HttpTrigger>
。
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.");
// ...
}
下列範例 host.json
檔案會新增記錄篩選。
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
},
"logLevel": {
"MyNamespace.HttpTrigger": "Information"
}
}
}
如需記錄層級的詳細資訊,請參閱 設定記錄層級。
函式應用程式提供的服務
功能主機會註冊多種服務。 下列服務是安全的,可視為應用程式中的相依性:
服務類型 | 壽命 | 說明 |
---|---|---|
Microsoft.Extensions.Configuration.IConfiguration |
單一 | 運行時間組態 |
Microsoft.Azure.WebJobs.Host.Executors.IHostIdProvider |
單一 | 負責提供主機實例的標識碼 |
如果您想要依賴其他服務,請在 GitHub 上建立問題並提出問題。
覆寫伺服器服務
目前不支援覆寫主機所提供的服務。 如果有您想要覆寫的服務,請建立問題,並在 GitHub 上提出。
使用選項和設定
在 應用程式設定 中定義的值可在 IConfiguration
實例中使用,這可讓您讀取啟動類別中的應用程式設定值。
您可以將 IConfiguration
實例中的值擷取成自定義型別。 將應用程式設定值複製到自定義類型,可讓您輕鬆地藉由插入這些值來測試您的服務。 讀取到組態實例的設定必須是簡單的索引鍵/值組。 針對在彈性進階方案中執行的函式,應用程式設定名稱只能包含字母、數位()、句號(0-9
.
)、冒號(:
)和底線(_
)。 如需詳細資訊,請參閱 應用程式設定考慮。
請考慮下列類別,其中包含名為 與應用程式設定一致的屬性:
public class MyOptions
{
public string MyCustomSetting { get; set; }
}
local.settings.json
以及可能會建構自定義設定的檔案,如下所示:
{
"IsEncrypted": false,
"Values": {
"MyOptions:MyCustomSetting": "Foobar"
}
}
在 Startup.Configure
方法內部,您可以從 IConfiguration
實體中擷取值到您的自訂類型,使用下列程式代碼:
builder.Services.AddOptions<MyOptions>()
.Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("MyOptions").Bind(settings);
});
呼叫 Bind
會將具有相符屬性名稱的值從組態複製到自定義實例。 選項實例現在可在IoC容器中使用,以插入函式。
options 物件會插入函式作為泛型 IOptions
介面的實例。 使用Value
屬性來存取您在配置中找到的值。
using System;
using Microsoft.Extensions.Options;
public class HttpTrigger
{
private readonly MyOptions _settings;
public HttpTrigger(IOptions<MyOptions> options)
{
_settings = options.Value;
}
}
如需詳細資訊,請參閱 ASP.NET Core 中的選項模式。
使用 ASP.NET Core 用戶密碼
當您在本機開發應用程式時,ASP.NET Core 提供 秘密管理員工具 ,可讓您將秘密資訊儲存在專案根目錄之外。 這會降低秘密不小心被提交到版本控制的可能性。 Azure Functions Core Tools(3.0.3233 版或更新版本)會自動讀取 ASP.NET 核心秘密管理員所建立的秘密。
若要將 .NET Azure Functions 專案設定為使用用戶密碼,請在專案根目錄中執行下列命令。
dotnet user-secrets init
使用dotnet user-secrets set
命令來建立或更新密碼。
dotnet user-secrets set MySecret "my secret value"
若要存取函式應用程式程式代碼中的使用者秘密值,請使用 IConfiguration
或 IOptions
。
自定義組態來源
若要指定其他的組態來源,請在您的函式應用程式的 ConfigureAppConfiguration
類別中覆蓋 StartUp
方法。
下列範例會新增基底和選擇性環境特定應用程式配置檔中的組態值。
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)
{
}
}
將組態提供者新增至 ConfigurationBuilder
的 IFunctionsConfigurationBuilder
屬性。 如需使用組態提供者的詳細資訊,請參閱 ASP.NET Core 中的組態。
FunctionsHostBuilderContext
從IFunctionsConfigurationBuilder.GetContext()
取得 。 使用此內容來擷取目前的環境名稱,並解析函式應用程式資料夾中組態檔的位置。
根據預設,這類 appsettings.json
組態檔不會自動複製到函式應用程式的輸出資料夾。 更新您的 .csproj
檔案以符合下列範例,以確保檔案已複製。
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
後續步驟
如需詳細資訊,請參閱下列資源: