共用方式為


在 .NET Azure Functions 中使用相依性插入

Azure Functions 支援相依性插入 (DI) 軟體設計模式,這是在類別與其相依性之間實現 控制反轉 (IoC) 的技術。

  • Azure Functions 中的相依性插入是以 .NET Core 相依性插入功能為基礎所建置。 建議熟悉 .NET Core 依賴注入。 在消耗性方案中,您覆寫相依性以及使用 Azure Functions 讀取組態值的方式有所不同。

  • 相依性插入的支援從 Azure Functions 2.x 開始。

  • 相依性插入模式會根據您的 C# 函式執行 進程內跨進程而有所不同。

這很重要

本文中的指引僅適用於在同進程中使用運行時間的 C# 類別庫函數。 此自定義相依性插入模型不適用於 .NET 隔離函式,可讓您跨進程執行 .NET 函式。 .NET 隔離工作處理程序模型依賴一般的 ASP.NET Core 相依性注入模式。 若要深入瞭解,請參閱 .NET 隔離工作者進程指南中的 相依注入

先決條件

您必須先安裝下列 NuGet 套件,才能使用相依性插入:

註冊服務

若要註冊服務,請建立方法來設定和新增元件至 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 設定的服務。 因此,函式專屬的類型,例如BindingContextExecutionContext,在安裝期間或作為可注入類型時均無法使用。

  • 不支援設定 ASP.NET 驗證。 Functions 主機會設定 ASP.NET 驗證服務,以正確公開核心生命周期作業的 API。 自定義 Startup 類別中的其他組態可以覆寫此組態,造成非預期的結果。 例如,呼叫 builder.Services.AddAuthentication() 可能會中斷入口網站與主機之間的驗證,導致出現 Azure Functions 執行環境無法連線 等訊息。

使用依賴注入

建構子注入可使您的相依性在函式中可用。 使用建構函式插入時,您不需要針對插入的服務或函式類別使用靜態類別。

下列範例示範如何將 IMyServiceHttpClient 相依性插入 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:單一服務存留期符合主機存留期,並可在該實例上的函式執行之間重複使用。 建議針對連線和用戶端使用單一存留期服務,例如 DocumentClientHttpClient 實例。

檢視或下載 GitHub 上 不同服務存留期的範例

記錄服務

如果您需要自己的記錄提供者,請將自訂型別註冊為 ILoggerProvider 的實例,該實例可透過 Microsoft.Extensions.Logging.Abstractions NuGet 套件取得。

Azure Functions 會自動新增 Application Insights。

警告

  • 請勿新增 AddApplicationInsightsTelemetry() 至服務集合,這會註冊與環境所提供的服務衝突的服務。
  • 如果您使用內建的 Application Insights 功能,請勿自行註冊 TelemetryConfigurationTelemetryClient。 如果您需要設定自己的 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"

若要存取函式應用程式程式代碼中的使用者秘密值,請使用 IConfigurationIOptions

自定義組態來源

若要指定其他的組態來源,請在您的函式應用程式的 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)
    {
    }
}

將組態提供者新增至 ConfigurationBuilderIFunctionsConfigurationBuilder屬性。 如需使用組態提供者的詳細資訊,請參閱 ASP.NET Core 中的組態。

FunctionsHostBuilderContextIFunctionsConfigurationBuilder.GetContext()取得 。 使用此內容來擷取目前的環境名稱,並解析函式應用程式資料夾中組態檔的位置。

根據預設,這類 appsettings.json 組態檔不會自動複製到函式應用程式的輸出資料夾。 更新您的 .csproj 檔案以符合下列範例,以確保檔案已複製。

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

後續步驟

如需詳細資訊,請參閱下列資源: