Skip to content

Commit 398f4cd

Browse files
committed
AddKeyedAzureBlobContainerClient
1 parent c42bb0d commit 398f4cd

File tree

4 files changed

+107
-21
lines changed

4 files changed

+107
-21
lines changed

playground/AzureStorageEndToEnd/AzureStorageEndToEnd.ApiService/Program.cs

+31-3
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,46 @@
99
builder.AddServiceDefaults();
1010

1111
builder.AddAzureBlobClient("blobs");
12-
builder.AddAzureBlobContainerClient("foocontainer");
12+
//builder.AddAzureBlobContainerClient("foocontainer");
13+
builder.AddKeyedAzureBlobContainerClient("mycontainer2");
14+
builder.AddKeyedAzureBlobContainerClient("foocontainer");
1315

1416
builder.AddAzureQueueClient("queues");
1517

1618
var app = builder.Build();
1719

1820
app.MapDefaultEndpoints();
19-
app.MapGet("/", async (BlobServiceClient bsc, QueueServiceClient qsc, BlobContainerClient bcc) =>
21+
22+
app.MapGet("/", async ([FromKeyedServices("mycontainer2")] BlobContainerClient keyedContainerClinet1,
23+
[FromKeyedServices("foocontainer")] BlobContainerClient keyedContainerClinet2) =>
2024
{
21-
var container = bsc.GetBlobContainerClient(blobContainerName: "test-container-1");
25+
var blobNames = new List<string>();
26+
var blobNameAndContent = Guid.NewGuid().ToString();
27+
28+
await keyedContainerClinet1.UploadBlobAsync(blobNameAndContent, new BinaryData(blobNameAndContent));
29+
await keyedContainerClinet2.UploadBlobAsync(blobNameAndContent, new BinaryData(blobNameAndContent));
30+
31+
var blobs = keyedContainerClinet1.GetBlobsAsync();
32+
blobNames.Add(keyedContainerClinet1.Uri.ToString());
33+
await foreach (var blob in blobs)
34+
{
35+
blobNames.Add(blob.Name);
36+
}
2237

38+
blobs = keyedContainerClinet2.GetBlobsAsync();
39+
blobNames.Add(keyedContainerClinet2.Uri.ToString());
40+
await foreach (var blob in blobs)
41+
{
42+
blobNames.Add(blob.Name);
43+
}
44+
45+
return blobNames;
46+
});
47+
app.MapGet("/test", async (BlobServiceClient bsc, QueueServiceClient qsc, BlobContainerClient fooContainerClinet) =>
48+
{
2349
var blobNameAndContent = Guid.NewGuid().ToString();
50+
51+
var container = bsc.GetBlobContainerClient(blobContainerName: "test-container-1");
2452
await container.UploadBlobAsync(blobNameAndContent, new BinaryData(blobNameAndContent));
2553

2654
var blobs = container.GetBlobsAsync();

playground/AzureStorageEndToEnd/AzureStorageEndToEnd.AppHost/Program.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
var blobs = storage.AddBlobs("blobs");
1212
blobs.AddBlobContainer("mycontainer1", blobContainerName: "test-container-1");
13-
blobs.AddBlobContainer("mycontainer2", blobContainerName: "test-container-2");
13+
var blobContainer1 = blobs.AddBlobContainer("mycontainer2", blobContainerName: "test-container-2");
1414

1515
var queues = storage.AddQueues("queues");
1616

@@ -24,6 +24,7 @@
2424
builder.AddProject<Projects.AzureStorageEndToEnd_ApiService>("api")
2525
.WithExternalHttpEndpoints()
2626
.WithReference(blobs).WaitFor(blobs)
27+
.WithReference(blobContainer1).WaitFor(blobContainer1)
2728
.WithReference(blobContainer2).WaitFor(blobContainer2)
2829
.WithReference(queues).WaitFor(queues);
2930

src/Components/Aspire.Azure.Storage.Blobs/AspireBlobStorageExtensions.cs

+73-16
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,23 @@ public static partial class AspireBlobStorageExtensions
1616
private const string DefaultConfigSectionName = "Aspire:Azure:Storage:Blobs";
1717

1818
/// <summary>
19-
/// Registers <see cref="BlobServiceClient"/> as a singleton in the services provided by the <paramref name="builder"/>.
20-
/// Enables retries, corresponding health check, logging and telemetry.
19+
/// Registers <see cref="BlobServiceClient"/> as a singleton in the services provided by the <paramref name="builder"/>.
20+
/// Enables retries, corresponding health check, logging and telemetry.
2121
/// </summary>
2222
/// <param name="builder">The <see cref="IHostApplicationBuilder" /> to read config from and add services to.</param>
23-
/// <param name="connectionName">A name used to retrieve the connection string from the ConnectionStrings configuration section.</param>
24-
/// <param name="configureSettings">An optional method that can be used for customizing the <see cref="AzureStorageBlobsSettings"/>. It's invoked after the settings are read from the configuration.</param>
25-
/// <param name="configureClientBuilder">An optional method that can be used for customizing the <see cref="IAzureClientBuilder{TClient, TOptions}"/>.</param>
23+
/// <param name="connectionName">
24+
/// A name used to retrieve the connection string from the ConnectionStrings configuration section.
25+
/// </param>
26+
/// <param name="configureSettings">
27+
/// An optional method that can be used for customizing the <see cref="AzureStorageBlobsSettings"/>. It's invoked after the settings are read from the configuration.
28+
/// </param>
29+
/// <param name="configureClientBuilder">
30+
/// An optional method that can be used for customizing the <see cref="IAzureClientBuilder{TClient, TOptions}"/>.
31+
/// </param>
2632
/// <remarks>Reads the configuration from "Aspire:Azure:Storage:Blobs" section.</remarks>
27-
/// <exception cref="InvalidOperationException">Thrown when neither <see cref="AzureStorageBlobsSettings.ConnectionString"/> nor <see cref="AzureStorageBlobsSettings.ServiceUri"/> is provided.</exception>
33+
/// <exception cref="InvalidOperationException">
34+
/// Neither <see cref="AzureStorageBlobsSettings.ConnectionString"/> nor <see cref="AzureStorageBlobsSettings.ServiceUri"/> is provided.
35+
/// </exception>
2836
public static void AddAzureBlobClient(
2937
this IHostApplicationBuilder builder,
3038
string connectionName,
@@ -38,15 +46,25 @@ public static void AddAzureBlobClient(
3846
}
3947

4048
/// <summary>
41-
/// Registers <see cref="BlobServiceClient"/> as a singleton for given <paramref name="name"/> in the services provided by the <paramref name="builder"/>.
42-
/// Enables retries, corresponding health check, logging and telemetry.
49+
/// Registers <see cref="BlobServiceClient"/> as a singleton for given <paramref name="name"/> in the services provided by the <paramref name="builder"/>.
50+
/// Enables retries, corresponding health check, logging and telemetry.
4351
/// </summary>
4452
/// <param name="builder">The <see cref="IHostApplicationBuilder" /> to read config from and add services to.</param>
45-
/// <param name="name">The name of the component, which is used as the <see cref="ServiceDescriptor.ServiceKey"/> of the service and also to retrieve the connection string from the ConnectionStrings configuration section.</param>
46-
/// <param name="configureSettings">An optional method that can be used for customizing the <see cref="AzureStorageBlobsSettings"/>. It's invoked after the settings are read from the configuration.</param>
47-
/// <param name="configureClientBuilder">An optional method that can be used for customizing the <see cref="IAzureClientBuilder{TClient, TOptions}"/>.</param>
53+
/// <param name="name">
54+
/// The name of the component, which is used as the <see cref="ServiceDescriptor.ServiceKey"/> of the service and also to retrieve
55+
/// the connection string from the ConnectionStrings configuration section.
56+
/// </param>
57+
/// <param name="configureSettings">
58+
/// An optional method that can be used for customizing the <see cref="AzureStorageBlobsSettings"/>.
59+
/// It's invoked after the settings are read from the configuration.
60+
/// </param>
61+
/// <param name="configureClientBuilder">
62+
/// An optional method that can be used for customizing the <see cref="IAzureClientBuilder{TClient, TOptions}"/>.
63+
/// </param>
4864
/// <remarks>Reads the configuration from "Aspire:Azure:Storage:Blobs:{name}" section.</remarks>
49-
/// <exception cref="InvalidOperationException">Thrown when neither <see cref="AzureStorageBlobsSettings.ConnectionString"/> nor <see cref="AzureStorageBlobsSettings.ServiceUri"/> is provided.</exception>
65+
/// <exception cref="InvalidOperationException">
66+
/// Neither <see cref="AzureStorageBlobsSettings.ConnectionString"/> nor <see cref="AzureStorageBlobsSettings.ServiceUri"/> is provided.
67+
/// </exception>
5068
public static void AddKeyedAzureBlobClient(
5169
this IHostApplicationBuilder builder,
5270
string name,
@@ -60,13 +78,18 @@ public static void AddKeyedAzureBlobClient(
6078
}
6179

6280
/// <summary>
63-
/// Registers <see cref="BlobContainerClient"/> as a singleton in the services provided by the <paramref name="builder"/>.
64-
/// Enables retries, corresponding health check, logging and telemetry.
81+
/// Registers <see cref="BlobContainerClient"/> as a singleton in the services provided by the <paramref name="builder"/>.
82+
/// Enables retries, corresponding health check, logging and telemetry.
6583
/// </summary>
6684
/// <param name="builder">The <see cref="IHostApplicationBuilder" /> to read config from and add services to.</param>
6785
/// <param name="connectionName">A name used to retrieve the connection string from the ConnectionStrings configuration section.</param>
68-
/// <param name="configureSettings">An optional method that can be used for customizing the <see cref="AzureStorageBlobsSettings"/>. It's invoked after the settings are read from the configuration.</param>
69-
/// <param name="configureClientBuilder">An optional method that can be used for customizing the <see cref="IAzureClientBuilder{TClient, TOptions}"/>.</param>
86+
/// <param name="configureSettings">
87+
/// An optional method that can be used for customizing the <see cref="AzureStorageBlobsSettings"/>.
88+
/// It's invoked after the settings are read from the configuration.
89+
/// </param>
90+
/// <param name="configureClientBuilder">
91+
/// An optional method that can be used for customizing the <see cref="IAzureClientBuilder{TClient, TOptions}"/>.
92+
/// </param>
7093
/// <remarks>Reads the configuration from "Aspire:Azure:Storage:Blobs" section.</remarks>
7194
/// <exception cref="InvalidOperationException">
7295
/// Neither <see cref="AzureStorageBlobsSettings.ConnectionString"/> nor <see cref="AzureStorageBlobsSettings.ServiceUri"/> is provided.
@@ -84,4 +107,38 @@ public static void AddAzureBlobContainerClient(
84107

85108
new BlobStorageContainerComponent().AddClient(builder, DefaultConfigSectionName, configureSettings, configureClientBuilder, connectionName, serviceKey: null);
86109
}
110+
111+
/// <summary>
112+
/// Registers <see cref="BlobContainerClient"/> as a singleton in the services provided by the <paramref name="builder"/>.
113+
/// Enables retries, corresponding health check, logging and telemetry.
114+
/// </summary>
115+
/// <param name="builder">The <see cref="IHostApplicationBuilder" /> to read config from and add services to.</param>
116+
/// <param name="name">
117+
/// The name of the component, which is used as the <see cref="ServiceDescriptor.ServiceKey"/> of the service and also to retrieve
118+
/// the connection string from the ConnectionStrings configuration section.
119+
/// </param>
120+
/// <param name="configureSettings">
121+
/// An optional method that can be used for customizing the <see cref="AzureStorageBlobsSettings"/>.
122+
/// It's invoked after the settings are read from the configuration.
123+
/// </param>
124+
/// <param name="configureClientBuilder">
125+
/// An optional method that can be used for customizing the <see cref="IAzureClientBuilder{TClient, TOptions}"/>.
126+
/// </param>
127+
/// <remarks>Reads the configuration from "Aspire:Azure:Storage:Blobs:{name}" section.</remarks>
128+
/// <exception cref="InvalidOperationException">
129+
/// Neither <see cref="AzureStorageBlobsSettings.ConnectionString"/> nor <see cref="AzureStorageBlobsSettings.ServiceUri"/> is provided.
130+
/// - or -
131+
/// <see cref="AzureBlobStorageContainerSettings.BlobContainerName"/> is not provided in the configuration section.
132+
/// </exception>
133+
public static void AddKeyedAzureBlobContainerClient(
134+
this IHostApplicationBuilder builder,
135+
string name,
136+
Action<AzureBlobStorageContainerSettings>? configureSettings = null,
137+
Action<IAzureClientBuilder<BlobContainerClient, BlobClientOptions>>? configureClientBuilder = null)
138+
{
139+
ArgumentNullException.ThrowIfNull(builder);
140+
ArgumentException.ThrowIfNullOrEmpty(name);
141+
142+
new BlobStorageContainerComponent().AddClient(builder, DefaultConfigSectionName, configureSettings, configureClientBuilder, connectionName: name, serviceKey: name);
143+
}
87144
}

src/Components/Aspire.Azure.Storage.Blobs/AzureBlobStorageContainerSettings.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ void IConnectionStringSettings.ParseConnectionString(string? connectionString)
4444
}
4545

4646
// We can't use connectionBuilder.ConnectionString here, because connectionBuilder escapes values
47-
// adding quotes and other characters, which upset the Azure SDK.
47+
// adding quotes and other characters, which upsets the Azure SDK.
4848
// So, we have rebuilt the connection string manually.
4949

5050
StringBuilder builder = new();

0 commit comments

Comments
 (0)