Menggunakan injeksi dependensi di .NET Azure Functions
Azure Functions mendukung pola desain perangkat lunak injeksi dependensi (DI), yang merupakan teknik untuk melakukan Inversion of Control (IoC) antara kelas dan dependensinya.
Injeksi dependensi di Azure Functions dibangun pada fitur Injeksi Dependensi Inti .NET. Sebaiknya Anda sudah memahami injeksi dependensi Inti .NET. Ada perbedaan dalam cara Anda mengganti dependensi dan bagaimana nilai konfigurasi dibaca dengan Azure Functions pada paket Konsumsi.
Dukungan untuk injeksi dependensi dimulai dengan Azure Functions 2.x.
Pola injeksi dependensi berbeda tergantung pada apakah fungsi C# Anda berjalan dalam proses atau di luar proses.
Penting
Panduan dalam artikel ini hanya berlaku untuk fungsi pustaka kelas C #, yang berjalan dalam proses dengan runtime. Model injeksi dependensi kustom ini tidak berlaku untuk fungsi terisolasi .NET, yang memungkinkan Anda menjalankan fungsi .NET di luar proses. Model proses pekerja terisolasi .NET bergantung pada pola injeksi dependensi Inti ASP.NET reguler. Untuk mempelajari lebih lanjut, lihat Injeksi dependensi dalam panduan proses pekerja terisolasi .NET.
Prasyarat
Sebelum dapat menggunakan injeksi dependensi, Anda harus menginstal paket NuGet berikut:
Paket Microsoft.NET.Sdk.Functions versi 1.0.28 atau yang lebih baru
Microsoft.Extensions.DependencyInjection (saat ini, hanya didukung versi 2.x atau lebih baru)
Mendaftarkan layanan
Untuk mendaftarkan layanan, buat metode untuk mengonfigurasi dan menambahkan komponen ke instansIFunctionsHostBuilder
. Host Azure Functions membuat contoh instans IFunctionsHostBuilder
dan meneruskannya langsung ke metode Anda.
Peringatan
Untuk aplikasi fungsi yang berjalan dalam paket Konsumsi atau Premium, modifikasi pada nilai konfigurasi yang digunakan dalam pemicu dapat menyebabkan kesalahan penskalaan. Setiap perubahan pada properti ini oleh kelas FunctionsStartup
akan menyebabkan kesalahan startup aplikasi fungsi.
Injeksi IConfiguration
dapat menyebabkan perilaku tak terduga. Untuk mempelajari selengkapnya tentang menambahkan sumber konfigurasi, lihat Menyesuaikan sumber konfigurasi.
Untuk mendaftarkan metode, tambahkan rakitan FunctionsStartup
atribut yang menentukan nama tipe yang digunakan selama startup.
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>();
}
}
Contoh ini menggunakan paket Microsoft.Extensions.Http yang diperlukan untuk mendaftarkan HttpClient
saat startup.
Peringatan
Serangkaian langkah pendaftaran berjalan sebelum dan sesudah runtime memproses kelas startup. Oleh karena itu, ingatlah item berikut:
Kelas startup dimaksudkan hanya untuk pengaturan dan pendaftaran. Hindari menggunakan layanan yang terdaftar di startup selama proses startup. Misalnya, jangan mencoba untuk mencatat pesan di pencatat yang sedang didaftarkan selama startup. Titik proses pendaftaran ini terlalu dini untuk menyiapkan fungsi layanan Anda.
Configure
Setelah metode dijalankan, runtime Functions terus mendaftarkan dependensi lain, yang dapat memengaruhi cara layanan Anda beroperasi.Kontainer injeksi dependensi hanya memegang jenis yang terdaftar secara eksplisit. Satu-satunya layanan yang tersedia sebagai jenis injeksi adalah apa yang disiapkan dalam
Configure
metode . Akibatnya, tipe spesifik Fungsi sepertiBindingContext
dan tidak tersedia selama pengaturan atau sebagai tipeExecutionContext
suntik.Mengonfigurasi autentikasi ASP.NET tidak didukung. Host Functions mengonfigurasi layanan autentikasi ASP.NET untuk mengekspos API dengan benar untuk operasi siklus hidup inti. Konfigurasi lain di kelas kustom
Startup
dapat mengambil alih konfigurasi ini, menyebabkan konsekuensi yang tidak diinginkan. Misalnya, panggilanbuilder.Services.AddAuthentication()
dapat memutuskan autentikasi antara portal dan host, yang mengarah ke pesan seperti runtime Azure Functions tidak dapat dijangkau.
Gunakan dependensi yang disuntikkan
Injeksi konstruktor digunakan untuk membuat dependensi Anda tersedia dalam fungsi. Penggunaan injeksi konstruktor mengharuskan Anda tidak menggunakan kelas statis untuk layanan yang disuntikkan atau untuk kelas fungsi Anda.
Contoh berikut menunjukkan bagaimana dependensi IMyService
dan HttpClient
disuntikkan ke fungsi yang dipicu 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.");
}
}
Contoh ini menggunakan paket Microsoft.Extensions.Http yang diperlukan untuk mendaftarkan HttpClient
saat startup.
Masa pakai layanan
Aplikasi Azure Functions menyediakan masa pakai layanan yang sama seperti Injeksi Dependensi ASP.NET . Untuk aplikasi Functions, masa pakai layanan yang berbeda berperilaku sebagai berikut:
- Sementara :Layanan sementara dibuat berdasarkan setiap resolusi layanan.
- Tercakup:Masa pakai tercakup sesuai dengan masa pakai eksekusi fungsi. Layanan tercakup dibuat sekali per eksekusi fungsi. Kemudian permintaan untuk layanan tersebut selama eksekusi menggunakan kembali instans layanan yang ada.
- Singleton: Masa pakai singleton cocok dengan masa pakai host dan digunakan kembali di seluruh eksekusi fungsi pada instans tersebut. Layanan seumur hidup Singleton direkomendasikan untuk koneksi dan klien, misalnya instans
DocumentClient
atauHttpClient
.
Lihat atau unduh sampel masa pakai layanan yang berbeda di GitHub.
Layanan pengelogan
Jika Anda memerlukan penyedia pembuatan log Anda sendiri, daftarkan jenis kustom sebagai contoh ILoggerProvider
, yang tersedia melalui paket NuGetMicrosoft.Extensions.Logging.Abstractions.
Application Insights ditambahkan oleh Azure Functions secara otomatis.
Peringatan
- Jangan tambahkan
AddApplicationInsightsTelemetry()
ke koleksi layanan, yang mendaftarkan layanan yang bertentangan dengan layanan yang disediakan oleh lingkungan. - Jangan daftarkan
TelemetryConfiguration
atauTelemetryClient
sendiri jika Anda menggunakan fungsionalitas Application Insights bawaan. Jika Anda perlu mengonfigurasi instansTelemetryClient
Anda sendiri, buat instans Anda melalui instans injeksiTelemetryConfiguration
seperti yang ditunjukkan dalam Log telemetri kustom dalam fungsi C #.
ILogger<T> dan ILoggerFactory
Host menginjeksi layanan ILogger<T>
dan ILoggerFactory
ke konstruktor. Namun, secara default filter logging baru ini difilter keluar dari log fungsi. Anda perlu mengubah host.json
file untuk ikut serta dalam filter dan kategori tambahan.
Contoh berikut menunjukkan cara menambahkan log ILogger<HttpTrigger>
yang diekspos ke host.
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.");
// ...
}
Contoh file host.json
berikut menambahkan filter log.
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
},
"logLevel": {
"MyNamespace.HttpTrigger": "Information"
}
}
}
Untuk informasi selengkapnya tentang tingkat log, lihat Mengonfigurasi tingkat log.
Aplikasi fungsi yang disediakan layanan
Host fungsi mendaftarkan banyak layanan. Layanan berikut ini aman untuk diambil sebagai dependensi dalam aplikasi Anda:
Jenis Layanan | Seumur hidup | Deskripsi |
---|---|---|
Microsoft.Extensions.Configuration.IConfiguration |
Singleton | Konfigurasi runtime |
Microsoft.Azure.WebJobs.Host.Executors.IHostIdProvider |
Singleton | Bertanggung jawab untuk memberikan ID instans host |
Jika ada layanan lain yang ingin Anda ambil dependensinya, buat masalah dan usulkan di GitHub.
Menimpa layanan host
Layanan penimpa yang disediakan oleh host saat ini tidak didukung. Jika ada layanan yang ingin Anda ganti, buat masalah dan usulkan di GitHub.
Bekerja dengan opsi dan pengaturan
Nilai yang ditentukan dalam pengaturan aplikasi yang tersedia dalam instans IConfiguration
, yang memungkinkan Anda membaca nilai pengaturan aplikasi di kelas startup.
Anda dapat mengekstrak nilai dari IConfiguration
instans menjadi tipe kustom. Menyalin nilai pengaturan aplikasi ke jenis kustom memudahkan pengujian layanan Anda dengan membuat nilai-nilai ini dapat diinjeksi. Pengaturan yang dibaca ke dalam instans konfigurasi haruslah pasangan kunci/nilai sederhana. Untuk fungsi yang berjalan dalam paket Elastic Premium, nama pengaturan aplikasi hanya dapat berisi huruf, angka (0-9
), titik (.
), titik dua (:
) dan garis bawah (_
). Untuk informasi selengkapnya, lihat Pertimbangan pengaturan aplikasi.
Pertimbangkan kelas berikut yang menyertakan properti bernama yang konsisten dengan setelan aplikasi:
public class MyOptions
{
public string MyCustomSetting { get; set; }
}
Dan file local.settings.json
yang mungkin menata pengaturan kustom sebagai berikut:
{
"IsEncrypted": false,
"Values": {
"MyOptions:MyCustomSetting": "Foobar"
}
}
Dari dalam metode Startup.Configure
, Anda dapat mengekstrak nilai dari instans IConfiguration
menjadi tipe kustom Anda menggunakan kode berikut:
builder.Services.AddOptions<MyOptions>()
.Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("MyOptions").Bind(settings);
});
Memanggil nilai salinan Bind
yang memiliki nama properti yang cocok dari konfigurasi ke dalam instans kustom. Pilihan instans sekarang tersedia dalam wadah IoC untuk diinjeksikan ke fungsi.
Objek opsi disuntikkan ke fungsi sebagai instans antarmuka IOptions
generik. Gunakan properti Value
untuk mengakses nilai yang ditemukan dalam konfigurasi Anda.
using System;
using Microsoft.Extensions.Options;
public class HttpTrigger
{
private readonly MyOptions _settings;
public HttpTrigger(IOptions<MyOptions> options)
{
_settings = options.Value;
}
}
Untuk informasi selengkapnya, lihat Pola opsi di ASP.NET Core.
Menggunakan rahasia pengguna ASP.NET Core
Saat Anda mengembangkan aplikasi secara lokal, ASP.NET Core menyediakan alat Secret Manager yang memungkinkan Anda menyimpan informasi rahasia di luar akar proyek. Hal ini mencegah rahasia secara tidak sengaja diterapkan pada kontrol sumber. Azure Functions Core Tools (versi 3.0.3233 atau yang lebih baru) secara otomatis membaca rahasia yang dibuat Secret Manager dari ASP.NET Core.
Untuk mengonfigurasi proyek .NET Azure Functions untuk menggunakan rahasia pengguna, jalankan perintah berikut di root proyek.
dotnet user-secrets init
Kemudian gunakan perintah dotnet user-secrets set
untuk membuat atau memperbarui rahasia.
dotnet user-secrets set MySecret "my secret value"
Untuk mengakses nilai rahasia pengguna dalam kode aplikasi fungsi Anda, gunakan IConfiguration
atau IOptions
.
Mengkustomisasi sumber konfigurasi
Untuk menentukan sumber konfigurasi lain, ambil alih ConfigureAppConfiguration
metode di kelas aplikasi StartUp
fungsi Anda.
Sampel berikut menambahkan nilai konfigurasi dari file pengaturan aplikasi dasar dan lingkungan khusus lingkungan opsional.
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)
{
}
}
Tambahkan penyedia konfigurasi ke properti ConfigurationBuilder
dari IFunctionsConfigurationBuilder
. Untuk informasi selengkapnya tentang menggunakan penyedia konfigurasi, lihat Konfigurasi di ASP.NET Core.
FunctionsHostBuilderContext
diperoleh dari IFunctionsConfigurationBuilder.GetContext()
. Gunakan konteks ini untuk mengambil nama lingkungan saat ini dan mengatasi lokasi file konfigurasi di folder aplikasi fungsi Anda.
Secara default, file konfigurasi seperti appsettings.json
tidak disalin secara otomatis ke folder output aplikasi fungsi. Perbarui file Anda .csproj
agar sesuai dengan sampel berikut untuk memastikan file disalin.
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
Langkah berikutnya
Untuk informasi selengkapnya, lihat sumber daya berikut: