.NET용 Azure SDK를 통해 종속성 주입
이 문서에서는 .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 파일이 있을 수 있습니다. 다른 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 serialization은 대/소문자를 구분하지 않는 방식으로 수행됩니다. 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
형식 인수에 매핑됩니다. 기본TokenCredential
은 Microsoft.Extensions.Azure.AzureClientFactoryBuilder.UseCredential(TokenCredential) 메서드 호출을 통해 설정되기 때문에 생성자의TokenCredential
변형이 사용됩니다.
서로 다른 이름을 사용하여 여러 서비스 클라이언트 구성
두 개의 스토리지 계정이 있다고 상상해 보세요. 하나는 개인 정보용이고 다른 하나는 공개 정보용입니다. 특정 작업 후 앱이 퍼블릭 스토리지 계정의 데이터를 프라이빗 스토리지 계정으로 전송합니다. 스토리지 서비스 클라이언트가 두 개 필요합니다. 이러한 두 클라이언트를 구분하려면 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