Azure SDK for .NET での依存関係の挿入
この記事では、.NET アプリでの依存関係の挿入のために、最新の .NET 向け Azure クライアント ライブラリから Azure サービス クライアントを登録する方法を示します。 すべての最新の .NET アプリは、Program.cs ファイルで指定されている指示に従って起動します。
パッケージのインストール
Azure.
プレフィックス付きパッケージからサービス クライアントを登録して構成するには、以下の操作を行います。
以下のプロジェクトに Microsoft.Extensions.Azure パッケージをインストールします。
dotnet add package Microsoft.Extensions.Azure
Azure.Identity パッケージをインストールして、このような型を受け入れるすべての登録済みクライアントの認証に使用する
TokenCredential
型を構成します。dotnet add package Azure.Identity
デモンストレーションの目的で、この記事のサンプル コードでは、Key Vault シークレット、Blob Storage、Service Bus、Azure OpenAI ライブラリを使用します。 次のパッケージをインストールして、以下の手順に従ってください。
dotnet add package Azure.Security.KeyVault.Secrets
dotnet add package Azure.Storage.Blobs
dotnet add package Azure.Messaging.ServiceBus
dotnet add package Azure.AI.OpenAI
クライアントとサブクライアントを登録する
サービス クライアントは、Azure サービスの API へのエントリ ポイントです。ライブラリ ユーザーは、サービスが提供するすべての操作を呼び出すことができ、最も一般的なシナリオを簡単に実装できます。 API の設計が簡素化され、サービス呼び出しのグループは、より小さなサブクライアント型を中心に編成できます。 たとえば、ServiceBusClient
はメッセージを発行するために ServiceBusSender
のサブクライアントを、またはメッセージを使用するために ServiceBusReceiver
のサブクライアントを追加登録できます。
Program.cs ファイルで、AddAzureClients 拡張メソッドを呼び出して、各サービスのクライアントを登録します。 次のコード サンプルには、Microsoft.AspNetCore.Builder
名前空間と Microsoft.Extensions.Hosting
名前空間のアプリケーション ビルダーに関するガイダンスが用意されています。
using Azure.Identity;
using Azure.Messaging.ServiceBus;
using Azure.Messaging.ServiceBus.Administration;
using Microsoft.Extensions.Azure;
using Azure.AI.OpenAI;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddAzureClients(async clientBuilder =>
{
// Register clients for each service
clientBuilder.AddSecretClient(new Uri("<key_vault_url>"));
clientBuilder.AddBlobServiceClient(new Uri("<storage_url>"));
clientBuilder.AddServiceBusClientWithNamespace(
"<your_namespace>.servicebus.windows.net");
// Set a credential for all clients to use by default
DefaultAzureCredential credential = new();
clientBuilder.UseCredential(credential);
// Register a subclient for each Service Bus Queue
List<string> queueNames = await GetQueueNames(credential);
foreach (string queue in queueNames)
{
clientBuilder.AddClient<ServiceBusSender, ServiceBusClientOptions>(
(_, _, provider) => provider.GetService<ServiceBusClient>()
.CreateSender(queue)).WithName(queue);
}
// Register a custom client factory
clientBuilder.AddClient<AzureOpenAIClient, AzureOpenAIClientOptions>(
(options, _, _) => new AzureOpenAIClient(
new Uri("<url_here>"), credential, options));
});
WebApplication app = builder.Build();
async Task<List<string>> GetQueueNames(DefaultAzureCredential credential)
{
// Query the available queues for the Service Bus namespace.
var adminClient = new ServiceBusAdministrationClient
("<your_namespace>.servicebus.windows.net", credential);
var queueNames = new List<string>();
// Because the result is async, the queue names need to be captured
// to a standard list to avoid async calls when registering. Failure to
// do so results in an error with the services collection.
await foreach (QueueProperties queue in adminClient.GetQueuesAsync())
{
queueNames.Add(queue.Name);
}
return queueNames;
}
上のコードでは以下の操作が行われます。
- Key Vault シークレット、Blob Storage、Service Bus クライアントは、それぞれ AddSecretClient、AddBlobServiceClient、AddServiceBusClientWithNamespace を使用して登録されます。
Uri
型、string
型の引数が渡されます。 URL を明示的に指定しないようにするには、「コードとは別に構成を格納する」のセクションを参照してください。 - DefaultAzureCredential は、登録されている各クライアントの
TokenCredential
引数要件を満たすために使用されます。 いずれかのクライアントが作成されると、DefaultAzureCredential
が認証に使用されます。 - Service Bus サブクライアントは、サブクライアントと対応するオプションの種類を使用して、サービス上の各キューに登録されます。 サブクライアントのキュー名は、サービス登録とは別のメソッドを使用して取得されます。これは、
GetQueuesAsync
メソッドを非同期的に実行する必要があるためです。 - Azure OpenAI クライアントは、クライアント インスタンスの作成方法を制御する AddClient メソッドを使用して、カスタム クライアント ファクトリを使用して登録されます。 カスタム クライアント ファクトリは、次の場合に役立ちます。
- クライアントの構築中に他の依存関係を使用する必要があります。
- 登録するサービス クライアントの登録拡張メソッドが存在しません。
登録済みクライアントを使用する
「クライアントとサブクライアントの登録」セクションの説明に従ってクライアントを登録した後に、それらを使用できます。 次の例では、コンストラクターの挿入を使用して Blob Storage クライアントおよび、ASP.NET Core API コントローラー の Service Bus センダー サブクライアントのファクトリを取得しています。
[ApiController]
[Route("[controller]")]
public class MyApiController : ControllerBase
{
private readonly BlobServiceClient _blobServiceClient;
private readonly ServiceBusSender _serviceBusSender;
public MyApiController(
BlobServiceClient blobServiceClient,
IAzureClientFactory<ServiceBusSender> senderFactory)
{
_blobServiceClient = blobServiceClient;
_serviceBusSender = senderFactory.CreateClient("myQueueName");
}
[HttpGet]
public async Task<IEnumerable<string>> Get()
{
BlobContainerClient containerClient =
_blobServiceClient.GetBlobContainerClient("demo");
var results = new List<string>();
await foreach (BlobItem blob in containerClient.GetBlobsAsync())
{
results.Add(blob.Name);
}
return results.ToArray();
}
}
コードとは別に構成を格納する
「クライアントとサブクライアントの登録」セクションでは、Uri
に型指定された変数をクライアント コンストラクターに明示的に渡しました。 このアプローチにより、開発および運用中に異なる環境に対してコードを実行するときに問題が発生するおそれがあります。 .NET チームは、このような構成を環境に依存する JSON ファイルに格納するように提案しています。 たとえば、appsettings.Development.json ファイルに開発環境の設定を含めることができます。 もう 1 つの appsettings.Production.json には、運用環境の設定などが含まれます。 ファイル形式は次のとおりです。
{
"AzureDefaults": {
"Diagnostics": {
"IsTelemetryDisabled": false,
"IsLoggingContentEnabled": true
},
"Retry": {
"MaxRetries": 3,
"Mode": "Exponential"
}
},
"KeyVault": {
"VaultUri": "https://mykeyvault.vault.azure.net"
},
"ServiceBus": {
"Namespace": "<your_namespace>.servicebus.windows.net"
},
"Storage": {
"ServiceUri": "https://mydemoaccount.storage.windows.net"
}
}
ClientOptions クラスから JSON ファイルに任意のプロパティを追加できます。 JSON 構成ファイルの設定は、IConfiguration を使用して取得できます。
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
builder.Configuration.GetSection("KeyVault"));
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("Storage"));
clientBuilder.AddServiceBusClientWithNamespace(
builder.Configuration["ServiceBus:Namespace"]);
clientBuilder.UseCredential(new DefaultAzureCredential());
// Set up any default settings
clientBuilder.ConfigureDefaults(
builder.Configuration.GetSection("AzureDefaults"));
});
上記の JSON の例では、次のように指定されています。
- 最上位レベルのキー名、
AzureDefaults
、KeyVault
、ServiceBus
、およびStorage
は任意です。 他のすべてのキー名は重要な意味を持ち、JSON シリアル化は大文字と小文字を区別しない方法で実行されます。 AzureDefaults.Retry
オブジェクト リテラル:- 再試行ポリシー構成設定を表します。
- Retry プロパティに対応します。 そのオブジェクト リテラル内に、MaxRetries プロパティに対応する
MaxRetries
キーがあります。
KeyVault:VaultUri
、ServiceBus:Namespace
、Storage:ServiceUri
キーの値はそれぞれ、Azure.Security.KeyVault.Secrets.SecretClient.SecretClient(Uri, TokenCredential, SecretClientOptions)、Azure.Messaging.ServiceBus.ServiceBusClient.ServiceBusClient(String)、Azure.Storage.Blobs.BlobServiceClient.BlobServiceClient(Uri, TokenCredential, BlobClientOptions) のコンストラクター オーバーロードのUri
およびstring
で型指定された引数にそれぞれマッピングされます。 Microsoft.Extensions.Azure.AzureClientFactoryBuilder.UseCredential(TokenCredential) メソッド呼び出しを介して既定値TokenCredential
が設定されるため、コンストラクターのTokenCredential
バリアントが使用されます。
異なる名前で複数のサービス クライアントを構成する
2 つのストレージ アカウントがあるとします。1 つは個人情報用で、もう 1 つは公開情報用です。 アプリでは、何らかの操作後に、パブリックからプライベート ストレージ アカウントにデータが転送されます。 2 つのストレージ サービス クライアントが必要です。 これら 2 つのクライアントを区別するには、WithName 拡張メソッドを使用します。
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("PublicStorage"));
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("PrivateStorage"))
.WithName("PrivateStorage");
});
例として ASP.NET Core コントローラーを使用して、IAzureClientFactory<TClient> インターフェイスを使用して名前付きサービス クライアントにアクセスします。
public class HomeController : Controller
{
private readonly BlobServiceClient _publicStorage;
private readonly BlobServiceClient _privateStorage;
public HomeController(
BlobServiceClient defaultClient,
IAzureClientFactory<BlobServiceClient> clientFactory)
{
_publicStorage = defaultClient;
_privateStorage = clientFactory.CreateClient("PrivateStorage");
}
}
名前のないサービス クライアントは、前と同じ方法で引き続き使用できます。 名前付きクライアントは付加的なものです。
新しい再試行ポリシーを構成する
ある時点で、サービス クライアントの既定の設定の変更が必要になる場合があります。 たとえば、さまざまな再試行設定が必要な場合や、別のサービス API バージョンを使用する場合です。 再試行の設定はグローバルに、またはサービスごとに行うことができます。 ASP.NET Core プロジェクトに次の appsettings.json ファイルがあるとします。
{
"AzureDefaults": {
"Retry": {
"maxRetries": 3
}
},
"KeyVault": {
"VaultUri": "https://mykeyvault.vault.azure.net"
},
"ServiceBus": {
"Namespace": "<your_namespace>.servicebus.windows.net"
},
"Storage": {
"ServiceUri": "https://store1.storage.windows.net"
},
"CustomStorage": {
"ServiceUri": "https://store2.storage.windows.net"
}
}
再試行ポリシーは、必要に応じて以下のように変更できます。
builder.Services.AddAzureClients(clientBuilder =>
{
// Establish the global defaults
clientBuilder.ConfigureDefaults(
builder.Configuration.GetSection("AzureDefaults"));
clientBuilder.UseCredential(new DefaultAzureCredential());
// A Key Vault Secrets client using the global defaults
clientBuilder.AddSecretClient(
builder.Configuration.GetSection("KeyVault"));
// A Blob Storage client with a custom retry policy
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("Storage"))
.ConfigureOptions(options => options.Retry.MaxRetries = 10);
clientBuilder.AddServiceBusClientWithNamespace(
builder.Configuration["ServiceBus:Namespace"])
.ConfigureOptions(options => options.RetryOptions.MaxRetries = 10);
// A named storage client with a different custom retry policy
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("CustomStorage"))
.WithName("CustomStorage")
.ConfigureOptions(options =>
{
options.Retry.Mode = Azure.Core.RetryMode.Exponential;
options.Retry.MaxRetries = 5;
options.Retry.MaxDelay = TimeSpan.FromSeconds(120);
});
});
また、appsettings.json ファイルに再試行ポリシーのオーバーライドを配置することもできます。
{
"KeyVault": {
"VaultUri": "https://mykeyvault.vault.azure.net",
"Retry": {
"maxRetries": 10
}
}
}
関連項目
.NET