Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de changer d’annuaire.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer d’annuaire.
Cet article explique comment inscrire des clients de service Azure à partir des dernières bibliothèques clientes Azure pour .NET pour l’injection de dépendances dans une application .NET. Chaque application .NET moderne démarre à l’aide des instructions fournies dans un fichier Program.cs.
Installer des packages
Pour inscrire et configurer des clients de service à partir d’un package avec préfixe Azure. :
Installez le package Microsoft.Extensions.Azure dans votre projet :
dotnet add package Microsoft.Extensions.AzureInstallez le package Azure.Identity pour configurer un type
TokenCredentialà utiliser pour authentifier tous les clients inscrits qui acceptent ce type :dotnet add package Azure.Identity
À des fins de démonstration, l’exemple de code de cet article utilise les bibliothèques Key Vault Secrets, Blob Storage, Service Bus et OpenAI. Installez ensuite les packages suivants :
dotnet add package Azure.Security.KeyVault.Secrets
dotnet add package Azure.Storage.Blobs
dotnet add package Azure.Messaging.ServiceBus
dotnet add package OpenAI
Inscrire des clients et des sous-clients
Un client de service est le point d’entrée de l’API d’un service Azure. À partir de celui-ci, les utilisateurs de bibliothèque peuvent appeler toutes les opérations que le service fournit et peuvent facilement implémenter les scénarios les plus courants. Pour simplifier la conception d’une API, les groupes d’appels de service peuvent être organisés en types de sous-clients plus petits. Par exemple, ServiceBusClient peut inscrire des sous-clients ServiceBusSender supplémentaires pour la publication des messages, ou des sous-clients ServiceBusReceiver pour la consommation des messages.
Dans le fichier Program.cs, appelez la méthode d’extension AddAzureClients pour inscrire un client pour chaque service. Les exemples de code suivants fournissent une aide sur les générateurs d’applications à partir des espaces de noms Microsoft.AspNetCore.Builder et Microsoft.Extensions.Hosting.
using Azure.Identity;
using Azure.Messaging.ServiceBus;
using Azure.Messaging.ServiceBus.Administration;
using Microsoft.Extensions.Azure;
using OpenAI;
using OpenAI.Responses;
using System.ClientModel.Primitives;
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");
// AddAzureClients implicitly creates a DefaultAzureCredential instance
// Create a credential manually to override the type or access it explicitly for DI registrations
// This example shows credential reuse for GetQueueNames and AddClient calls downstream
DefaultAzureCredential credential = new();
clientBuilder.UseCredential(credential);
// Register a subclient for each Service Bus Queue
List<string> queueNames = await GetQueueNames(credential);
foreach (string queueName in queueNames)
{
clientBuilder.AddClient<ServiceBusSender, ServiceBusClientOptions>((_, _, provider) =>
provider.GetService(typeof(ServiceBusClient)) switch
{
ServiceBusClient client => client.CreateSender(queueName),
_ => throw new InvalidOperationException("Unable to create ServiceBusClient")
}).WithName(queueName);
}
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is required.");
// Register a custom client factory
#pragma warning disable OPENAI001 // Type is for evaluation purposes and is subject to change in future updates.
clientBuilder.AddClient<ResponsesClient, OpenAIClientOptions>(
(options, credential, _) => new ResponsesClient(
"<deployment_name>",
new BearerTokenPolicy(credential, "https://ai.azure.com/.default"),
new OpenAIClientOptions { Endpoint = new Uri($"{endpoint}/openai/v1/") }
));
#pragma warning restore OPENAI001
});
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;
}
Dans le code précédent :
- Les clients Secrets Key Vault, Stockage Blob et Service Bus sont inscrits à l’aide de AddSecretClient, AddBlobServiceClient et AddServiceBusClientWithNamespace, respectivement. Les arguments de type
Urietstringsont passés. Pour éviter de spécifier explicitement ces URL, consultez la section Stocker la configuration séparément du code. - Chaque client inscrit utilise automatiquement DefaultAzureCredential pour
TokenCredential, sauf si vous configurez un type d’identifiants différent (par exemple, à l’aide deWithCredential). - Les sous-clients de Service Bus sont inscrits pour chaque file d’attente du service à l’aide du sous-client et des types d’options correspondants. Les noms de files d’attente des sous-clients sont récupérés à l’aide d’une méthode distincte en dehors de l’inscription du service, car la méthode
GetQueuesAsyncdoit être exécutée de manière asynchrone. - Un
ResponsesClientest inscrit à l’aide d’une fabrique de clients personnalisée via la méthode AddClient, qui permet de contrôler la façon dont une instance de client est créée. Les fabriques clientes personnalisées sont utiles dans les cas suivants :- Vous devez utiliser d’autres dépendances pendant la construction du client.
- Une méthode d’extension d’inscription n’existe pas pour le client de service que vous souhaitez inscrire.
Utiliser les clients inscrits
Une fois les clients inscrits, comme indiqué dans la section Inscrire des clients et des sous-clients, vous pouvez désormais les utiliser. Dans l’exemple suivant, l’injection de constructeurr est utilisée pour obtenir le client Blob Storage et une fabrique de sous-clients d’expéditeur de bus de services dans un contrôleur API ASP.NET Core :
[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();
}
}
Stocker la configuration séparément du code
Dans la section Inscrire des clients et des sous-clients, vous avez passé explicitement les variables de type Uri aux constructeurs clients. Cette approche peut entraîner des problèmes lorsque vous exécutez du code sur différents environnements pendant le développement et la production. L’équipe .NET suggère de stocker ces configurations dans des fichiers JSON dépendant de l’environnement. Par exemple, vous pouvez avoir un fichier appsettings.Development.json contenant les paramètres d’environnement de développement. Un autre fichier appsettings.Production.json contient des paramètres d’environnement de production, etc. Le format de fichier est :
{
"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"
}
}
Vous pouvez ajouter des propriétés de la classe ClientOptions dans le fichier JSON. Les paramètres du fichier de configuration JSON peuvent être récupérés à l’aide de IConfiguration.
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
builder.Configuration.GetSection("KeyVault"));
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("Storage"));
clientBuilder.AddServiceBusClientWithNamespace(
builder.Configuration["ServiceBus:Namespace"]);
// Set up any default settings
clientBuilder.ConfigureDefaults(
builder.Configuration.GetSection("AzureDefaults"));
});
Dans l’exemple JSON précédent :
- Les noms de clés de premier niveau,
AzureDefaults,KeyVault,ServiceBusetStorage, sont arbitraires. Tous les autres noms de clé sont significatifs, et la sérialisation JSON est effectuée de manière non sensible à la casse. - Littéral d’objet
AzureDefaults.Retry:- Représente les paramètres de configuration de la stratégie de nouvelles tentatives.
- Correspond à la propriété Retry. Dans ce littéral d’objet, vous trouverez la clé
MaxRetries, qui correspond à la propriété MaxRetries.
- Les valeurs de clé
KeyVault:VaultUri,ServiceBus:NamespaceetStorage:ServiceUrisont mappées aux arguments de typeUrietstringdes surcharges de constructeur Azure.Security.KeyVault.Secrets.SecretClient.SecretClient(Uri, TokenCredential, SecretClientOptions), Azure.Messaging.ServiceBus.ServiceBusClient.ServiceBusClient(String) et Azure.Storage.Blobs.BlobServiceClient.BlobServiceClient(Uri, TokenCredential, BlobClientOptions), respectivement.
Configurer plusieurs clients de service avec des noms différents
Supposons que vous disposez de deux comptes de stockage : un pour les informations privées et un autre pour les informations publiques. Votre application transfère des données du compte de stockage public vers le privé après une opération. Vous devez avoir deux clients de service de stockage. Pour différencier ces deux clients, utilisez la méthode d’extension WithName :
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("PublicStorage"));
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("PrivateStorage"))
.WithName("PrivateStorage");
});
En utilisant un contrôleur ASP.NET Core comme exemple, accédez au client de service nommé à l’aide de l’interface 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");
}
}
Le client de service sans nom est toujours disponible, de la même manière qu’auparavant. Les clients nommés sont additifs.
Configurer une nouvelle stratégie de nouvelles tentatives
À un moment donné, vous pouvez modifier les paramètres par défaut d’un client de service. Par exemple, vous pouvez souhaiter des paramètres de nouvelles tentatives différents ou utiliser une autre version de l’API de service. Vous pouvez définir les paramètres de nouvelles tentatives globalement ou par service. Supposons que vous disposez du fichier appsettings.json suivant dans votre projet ASP.NET Core :
{
"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"
}
}
Vous pouvez modifier la stratégie de nouvelles tentatives en fonction de vos besoins, comme suit :
builder.Services.AddAzureClients(clientBuilder =>
{
// Establish the global defaults
clientBuilder.ConfigureDefaults(
builder.Configuration.GetSection("AzureDefaults"));
// 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);
});
});
Vous pouvez également placer des remplacements de stratégie de nouvelles tentatives dans le fichier appsettings.json :
{
"KeyVault": {
"VaultUri": "https://mykeyvault.vault.azure.net",
"Retry": {
"maxRetries": 10
}
}
}