Afhankelijkheidsinjectie met de Azure SDK voor .NET
In dit artikel wordt beschreven hoe u Azure-serviceclients registreert uit de nieuwste Azure-clientbibliotheken voor .NET voor afhankelijkheidsinjectie in een .NET-app. Elke moderne .NET-app wordt gestart met behulp van de instructies in een Program.cs-bestand .
Pakketten installeren
Serviceclients registreren en configureren vanuit een Azure.
-voorvoegselpakket:
Installeer het pakket Microsoft.Extensions.Azure in uw project:
dotnet add package Microsoft.Extensions.Azure
Installeer het Azure.Identity-pakket om een
TokenCredential
type te configureren dat moet worden gebruikt voor het verifiëren van alle geregistreerde clients die een dergelijk type accepteren:dotnet add package Azure.Identity
Voor demonstratiedoeleinden gebruikt de voorbeeldcode in dit artikel de Key Vault-geheimen, Blob Storage-, Service Bus- en Azure OpenAI-bibliotheken. Installeer de volgende pakketten om mee te doen:
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
Clients en subclients registreren
Een serviceclient is het toegangspunt voor de API voor een Azure-service: bibliotheekgebruikers kunnen alle bewerkingen die de service biedt aanroepen en kunnen eenvoudig de meest voorkomende scenario's implementeren. Waar het ontwerp van een API wordt vereenvoudigd, kunnen groepen serviceaanroepen worden georganiseerd rond kleinere subclienttypen. U kunt bijvoorbeeld ServiceBusClient
extra ServiceBusSender
subclients registreren voor het publiceren van berichten of ServiceBusReceiver
subclients voor het gebruiken van berichten.
Roep in het Program.cs-bestand de AddAzureClients extensiemethode aan om een client voor elke service te registreren. De volgende codevoorbeelden bieden richtlijnen voor toepassingsbouwers uit de Microsoft.AspNetCore.Builder
en Microsoft.Extensions.Hosting
naamruimten.
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;
}
In de voorgaande code:
- Key Vault-geheimen, Blob Storage- en Service Bus-clients worden geregistreerd met respectievelijk de AddSecretClient, AddBlobServiceClient en AddServiceBusClientWithNamespace. De
Uri
argumenten - enstring
-getypt worden doorgegeven. Als u wilt voorkomen dat u deze URL's expliciet opgeeft, raadpleegt u de Store-configuratie afzonderlijk van de codesectie . - DefaultAzureCredential wordt gebruikt om te voldoen aan de
TokenCredential
argumentvereiste voor elke geregistreerde client. Wanneer een van de clients wordt gemaakt,DefaultAzureCredential
wordt gebruikt om te verifiëren. - Service Bus-subclients worden geregistreerd voor elke wachtrij op de service met behulp van de subclient en de bijbehorende optiestypen. De wachtrijnamen voor de subclients worden opgehaald met behulp van een afzonderlijke methode buiten de serviceregistratie, omdat de
GetQueuesAsync
methode asynchroon moet worden uitgevoerd. - Een Azure OpenAI-client wordt geregistreerd met behulp van een aangepaste clientfactory via de AddClient methode, die controle biedt over de manier waarop een clientexemplaren worden gemaakt. Aangepaste client factory's zijn handig in de volgende gevallen:
- U moet andere afhankelijkheden gebruiken tijdens de clientconstructie.
- Er bestaat geen registratieextensiemethode voor de serviceclient die u wilt registreren.
De geregistreerde clients gebruiken
Als de clients zijn geregistreerd, zoals beschreven in de sectie Clients en subclients registreren, kunt u deze nu gebruiken. In het volgende voorbeeld wordt constructorinjectie gebruikt voor het verkrijgen van de Blob Storage-client en een factory voor Service Bus-afzendersubclients in een ASP.NET Core API-controller:
[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();
}
}
Configuratie afzonderlijk van code opslaan
In de sectie Clients en subclients registreren hebt u de Uri
door u getypte variabelen expliciet doorgegeven aan de clientconstructors. Deze aanpak kan problemen veroorzaken wanneer u tijdens de ontwikkeling en productie code uitvoert op verschillende omgevingen. Het .NET-team stelt voor om dergelijke configuraties op te slaan in omgevingsafhankelijke JSON-bestanden. U kunt bijvoorbeeld appsettings hebben. Development.json bestand met instellingen voor de ontwikkelomgeving. Andere appsettings. Production.json bestand zou instellingen voor de productieomgeving bevatten, enzovoort. De bestandsindeling is:
{
"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"
}
}
U kunt alle eigenschappen uit de ClientOptions klasse toevoegen aan het JSON-bestand. De instellingen in het JSON-configuratiebestand kunnen worden opgehaald met behulp van 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"));
});
In het voorgaande JSON-voorbeeld:
- De sleutelnamen op het hoogste niveau,
AzureDefaults
,KeyVault
,ServiceBus
enStorage
, zijn willekeurig. Alle andere sleutelnamen hebben significantie en JSON-serialisatie wordt op een niet-hoofdlettergevoelige manier uitgevoerd. - De
AzureDefaults.Retry
letterlijke object:- Vertegenwoordigt de beleidsconfiguratie-instellingen voor opnieuw proberen.
- Komt overeen met de Retry eigenschap. Binnen het letterlijke object vindt u de
MaxRetries
sleutel die overeenkomt met de MaxRetries eigenschap.
- De , en sleutelwaarden zijn respectievelijk toegewezen aan de
Uri
- enstring
-getypte argumenten van de Azure.Security.KeyVault.Secrets.SecretClient.SecretClient(Uri, TokenCredential, SecretClientOptions), Azure.Messaging.ServiceBus.ServiceBusClient.ServiceBusClient(String)en constructoroverbelastingenAzure.Storage.Blobs.BlobServiceClient.BlobServiceClient(Uri, TokenCredential, BlobClientOptions).Storage:ServiceUri
ServiceBus:Namespace
KeyVault:VaultUri
DeTokenCredential
varianten van de constructors worden gebruikt omdat een standaardwaardeTokenCredential
wordt ingesteld via de Microsoft.Extensions.Azure.AzureClientFactoryBuilder.UseCredential(TokenCredential) methode-aanroep.
Meerdere serviceclients met verschillende namen configureren
Stel dat u twee opslagaccounts hebt: één voor persoonlijke gegevens en een andere voor openbare informatie. Uw app draagt gegevens over van het publiek naar het privéopslagaccount na een bepaalde bewerking. U moet twee opslagserviceclients hebben. Gebruik de WithName extensiemethode om onderscheid te maken tussen deze twee clients:
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("PublicStorage"));
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("PrivateStorage"))
.WithName("PrivateStorage");
});
Als u een ASP.NET Core-controller als voorbeeld gebruikt, opent u de benoemde serviceclient met behulp van de IAzureClientFactory<TClient> interface:
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");
}
}
De niet-benoemde serviceclient is nog steeds op dezelfde manier beschikbaar als voorheen. Benoemde clients zijn additief.
Een nieuw beleid voor opnieuw proberen configureren
Op een bepaald moment kunt u de standaardinstellingen voor een serviceclient wijzigen. U kunt bijvoorbeeld verschillende instellingen voor opnieuw proberen of een andere service-API-versie gebruiken. U kunt de instellingen voor opnieuw proberen globaal of per service instellen. Stel dat u het volgende appsettings.json-bestand in uw ASP.NET Core-project hebt:
{
"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"
}
}
U kunt het beleid voor opnieuw proberen zo aanpassen aan uw behoeften:
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);
});
});
U kunt ook beleidsoverschrijvingen voor opnieuw proberen in het appsettings.json-bestand plaatsen:
{
"KeyVault": {
"VaultUri": "https://mykeyvault.vault.azure.net",
"Retry": {
"maxRetries": 10
}
}
}