From 0ddf5ef9fa73dbd5feb94038c7c25b19dd70f904 Mon Sep 17 00:00:00 2001 From: David Pine Date: Thu, 2 Nov 2023 10:06:59 -0500 Subject: [PATCH 1/4] Last round of triple slash, I believe. --- .editorconfig | 2 +- Aspire.sln | 3 ++ eng/common/templates/job/job.yml | 2 +- .../BasketService/Protos/basket.proto | 2 +- .../Components/Controls/LogViewer.razor.cs | 2 +- .../Dialogs/SettingsDialog.razor.cs | 2 +- .../AzureProvisionerExtensions.cs | 9 ++-- ...rOptions.cs => AzureProvisionerOptions.cs} | 2 +- .../JsonExtensions.cs | 1 + .../AppConfigurationProvisoner.cs | 4 +- .../Provisioners/AzureProvisioner.cs | 14 +++--- .../Provisioners/KeyVaultProvisoner.cs | 4 +- .../Provisioners/ServiceBusProvisioner.cs | 2 +- .../Provisioners/StorageProvisioner.cs | 6 +-- .../UserSecretsPathHelper.cs | 3 ++ .../AzureAppConfigurationResource.cs | 11 ++++ .../AzureBlobStorageResource.cs | 26 ++++++++++ .../AzureKeyVaultResource.cs | 11 ++++ .../AzureQueueStorageResource.cs | 26 ++++++++++ .../AzureRedisResource.cs | 11 ++++ .../AzureResourceExtensions.cs | 3 ++ .../AzureServiceBusResource.cs | 20 +++++++- .../AzureStorageResource.cs | 50 +++++++------------ .../AzureTableStorageResource.cs | 26 ++++++++++ src/Aspire.Hosting.Azure/IAzureResource.cs | 5 +- src/Aspire.Hosting/DistributedApplication.cs | 3 +- .../AspireTablesExtensions.cs | 3 ++ .../AspireServiceBusExtensions.cs | 3 ++ .../AspireKeyVaultExtensions.cs | 3 ++ .../AspireBlobStorageExtensions.cs | 3 ++ .../AspireQueueStorageExtensions.cs | 4 ++ ...spireSqlServerEFCoreSqlClientExtensions.cs | 2 +- .../README.md | 2 +- .../AspireEFPostgreSqlExtensions.cs | 7 ++- .../README.md | 2 +- .../AspireRedisDistributedCacheExtensions.cs | 3 ++ .../AspireRedisOutputCacheExtensions.cs | 3 ++ .../AspireRedisExtensions.cs | 3 ++ .../Features/IEndPointHealthFeature.cs | 10 +++- .../Features/IEndPointLoadFeature.cs | 7 ++- 40 files changed, 238 insertions(+), 67 deletions(-) rename src/Aspire.Hosting.Azure.Provisioning/{AzureProvisinerOptions.cs => AzureProvisionerOptions.cs} (89%) create mode 100644 src/Aspire.Hosting.Azure/AzureBlobStorageResource.cs create mode 100644 src/Aspire.Hosting.Azure/AzureQueueStorageResource.cs create mode 100644 src/Aspire.Hosting.Azure/AzureTableStorageResource.cs diff --git a/.editorconfig b/.editorconfig index 72837be992..5b5e8b1139 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,7 +4,7 @@ ; ; Here are some resources for what's supported for .NET/C# ; https://kent-boogaart.com/blog/editorconfig-reference-for-c-developers -; https://learn.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference +; https://learn.microsoft.com/visualstudio/ide/editorconfig-code-style-settings-reference ; ; Be **careful** editing this because some of the rules don't support adding a severity level ; For instance if you change to `dotnet_sort_system_directives_first = true:warning` (adding `:warning`) diff --git a/Aspire.sln b/Aspire.sln index 5647600b1a..4e351b8598 100644 --- a/Aspire.sln +++ b/Aspire.sln @@ -137,6 +137,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CatalogDb", "samples\eShopL EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{991DB378-6CB5-4441-BFC3-657400690FC3}" ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets Directory.Packages.props = Directory.Packages.props EndProjectSection EndProject diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index e20ee3a983..8e63edc762 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -76,7 +76,7 @@ jobs: - name: EnableRichCodeNavigation value: 'true' # Retry signature validation up to three times, waiting 2 seconds between attempts. - # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures + # See https://learn.microsoft.com/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY value: 3,2000 - ${{ each variable in parameters.variables }}: diff --git a/samples/eShopLite/BasketService/Protos/basket.proto b/samples/eShopLite/BasketService/Protos/basket.proto index 245a37b73a..5dc6e9ac6f 100644 --- a/samples/eShopLite/BasketService/Protos/basket.proto +++ b/samples/eShopLite/BasketService/Protos/basket.proto @@ -47,7 +47,7 @@ message DeleteCustomerBasketRequest { message DeleteCustomerBasketResponse { } -// See: https://learn.microsoft.com/en-us/dotnet/architecture/grpc-for-wcf-developers/protobuf-data-types#decimals +// See: https://learn.microsoft.com/dotnet/architecture/grpc-for-wcf-developers/protobuf-data-types#decimals // Example: 12345.6789 -> { units = 12345, nanos = 678900000 } message DecimalValue { diff --git a/src/Aspire.Dashboard/Components/Controls/LogViewer.razor.cs b/src/Aspire.Dashboard/Components/Controls/LogViewer.razor.cs index 28a0c419c4..ab4b89ef82 100644 --- a/src/Aspire.Dashboard/Components/Controls/LogViewer.razor.cs +++ b/src/Aspire.Dashboard/Components/Controls/LogViewer.razor.cs @@ -77,7 +77,7 @@ public async ValueTask DisposeAsync() } catch (JSDisconnectedException) { - // Per https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/?view=aspnetcore-7.0#javascript-interop-calls-without-a-circuit + // Per https://learn.microsoft.com/aspnet/core/blazor/javascript-interoperability/?view=aspnetcore-7.0#javascript-interop-calls-without-a-circuit // this is one of the calls that will fail if the circuit is disconnected, and we just need to catch the exception so it doesn't pollute the logs } } diff --git a/src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor.cs b/src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor.cs index bdb5f1e4ca..fe1e94a53f 100644 --- a/src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor.cs +++ b/src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor.cs @@ -83,7 +83,7 @@ public async ValueTask DisposeAsync() } catch (JSDisconnectedException) { - // Per https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/?view=aspnetcore-7.0#javascript-interop-calls-without-a-circuit + // Per https://learn.microsoft.com/aspnet/core/blazor/javascript-interoperability/?view=aspnetcore-7.0#javascript-interop-calls-without-a-circuit // this is one of the calls that will fail if the circuit is disconnected, and we just need to catch the exception so it doesn't pollute the logs } } diff --git a/src/Aspire.Hosting.Azure.Provisioning/AzureProvisionerExtensions.cs b/src/Aspire.Hosting.Azure.Provisioning/AzureProvisionerExtensions.cs index 5a4d5fee33..ea5fa6ae2e 100644 --- a/src/Aspire.Hosting.Azure.Provisioning/AzureProvisionerExtensions.cs +++ b/src/Aspire.Hosting.Azure.Provisioning/AzureProvisionerExtensions.cs @@ -16,6 +16,9 @@ namespace Aspire.Hosting; +/// +/// Provides extension methods for adding support for generating Azure resources dynamically during application startup. +/// public static class AzureProvisionerExtensions { /// @@ -27,11 +30,11 @@ public static IDistributedApplicationBuilder AddAzureProvisioning(this IDistribu builder.Services.AddLifecycleHook(); // Attempt to read azure configuration from configuration - builder.Services.AddOptions() + builder.Services.AddOptions() .BindConfiguration("Azure"); // We're adding 2 because there's no easy way to enumerate all keys and all service types - builder.AddAzureProvisioner(); + builder.AddAzureProvisioner(); builder.AddResourceEnumerator(resourceGroup => resourceGroup.GetKeyVaults(), resource => resource.Data.Tags); builder.AddAzureProvisioner(); @@ -43,7 +46,7 @@ public static IDistributedApplicationBuilder AddAzureProvisioning(this IDistribu builder.AddAzureProvisioner(); builder.AddResourceEnumerator(resourceGroup => resourceGroup.GetAllRedis(), resource => resource.Data.Tags); - builder.AddAzureProvisioner(); + builder.AddAzureProvisioner(); builder.AddResourceEnumerator(resourceGroup => resourceGroup.GetAppConfigurationStores(), resource => resource.Data.Tags); return builder; } diff --git a/src/Aspire.Hosting.Azure.Provisioning/AzureProvisinerOptions.cs b/src/Aspire.Hosting.Azure.Provisioning/AzureProvisionerOptions.cs similarity index 89% rename from src/Aspire.Hosting.Azure.Provisioning/AzureProvisinerOptions.cs rename to src/Aspire.Hosting.Azure.Provisioning/AzureProvisionerOptions.cs index 73cd065438..a469c5d9f5 100644 --- a/src/Aspire.Hosting.Azure.Provisioning/AzureProvisinerOptions.cs +++ b/src/Aspire.Hosting.Azure.Provisioning/AzureProvisionerOptions.cs @@ -3,7 +3,7 @@ namespace Aspire.Hosting.Azure.Provisioning; -internal sealed class AzureProvisinerOptions +internal sealed class AzureProvisionerOptions { public string? SubscriptionId { get; set; } diff --git a/src/Aspire.Hosting.Azure.Provisioning/JsonExtensions.cs b/src/Aspire.Hosting.Azure.Provisioning/JsonExtensions.cs index 6c8ef6baa8..2e48296bd5 100644 --- a/src/Aspire.Hosting.Azure.Provisioning/JsonExtensions.cs +++ b/src/Aspire.Hosting.Azure.Provisioning/JsonExtensions.cs @@ -1,5 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. + using System.Text.Json.Nodes; namespace Aspire.Hosting.Azure; diff --git a/src/Aspire.Hosting.Azure.Provisioning/Provisioners/AppConfigurationProvisoner.cs b/src/Aspire.Hosting.Azure.Provisioning/Provisioners/AppConfigurationProvisoner.cs index ac74ef7594..3fcf8c442e 100644 --- a/src/Aspire.Hosting.Azure.Provisioning/Provisioners/AppConfigurationProvisoner.cs +++ b/src/Aspire.Hosting.Azure.Provisioning/Provisioners/AppConfigurationProvisoner.cs @@ -15,7 +15,7 @@ namespace Aspire.Hosting.Azure.Provisioning; -internal sealed class AppConfigurationProvisoner(ILogger logger) : AzureResourceProvisioner +internal sealed class AppConfigurationProvisioner(ILogger logger) : AzureResourceProvisioner { public override bool ConfigureResource(IConfiguration configuration, AzureAppConfigurationResource resource) { @@ -72,7 +72,7 @@ public override async Task GetOrCreateResourceAsync( connectionStrings[resource.Name] = resource.Endpoint; // App Configuration Data Owner - // https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#app-configuration-data-owner + // https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#app-configuration-data-owner var roleDefinitionId = CreateRoleDefinitionId(subscription, "5ae67dd6-50cb-40e7-96ff-dc2bfa4b606b"); await DoRoleAssignmentAsync(armClient, appConfigurationResource.Id, principalId, roleDefinitionId, cancellationToken).ConfigureAwait(false); diff --git a/src/Aspire.Hosting.Azure.Provisioning/Provisioners/AzureProvisioner.cs b/src/Aspire.Hosting.Azure.Provisioning/Provisioners/AzureProvisioner.cs index 12c92e67ff..c7a6fb2124 100644 --- a/src/Aspire.Hosting.Azure.Provisioning/Provisioners/AzureProvisioner.cs +++ b/src/Aspire.Hosting.Azure.Provisioning/Provisioners/AzureProvisioner.cs @@ -24,7 +24,7 @@ namespace Aspire.Hosting.Azure; // Provisions azure resources for development purposes internal sealed class AzureProvisioner( - IOptions options, + IOptions options, IOptions publishingOptions, IConfiguration configuration, IHostEnvironment environment, @@ -34,7 +34,7 @@ internal sealed class AzureProvisioner( { internal const string AspireResourceNameTag = "aspire-resource-name"; - private readonly AzureProvisinerOptions _options = options.Value; + private readonly AzureProvisionerOptions _options = options.Value; public async Task BeforeStartAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken = default) { @@ -186,21 +186,21 @@ await PopulateExistingAspireResources( { usedResources.Add(resource.Name); - var provisoner = serviceProvider.GetKeyedService(resource.GetType()); + var provisioner = serviceProvider.GetKeyedService(resource.GetType()); - if (provisoner is null) + if (provisioner is null) { logger.LogWarning("No provisioner found for {resourceType} skipping.", resource.GetType().Name); continue; } - if (!provisoner.ShouldProvision(configuration, resource)) + if (!provisioner.ShouldProvision(configuration, resource)) { logger.LogInformation("Skipping {resourceName} because it is not configured to be provisioned.", resource.Name); continue; } - if (provisoner.ConfigureResource(configuration, resource)) + if (provisioner.ConfigureResource(configuration, resource)) { logger.LogInformation("Using connection information stored in user secrets for {resourceName}.", resource.Name); @@ -217,7 +217,7 @@ await PopulateExistingAspireResources( resourceMap ??= await resourceMapLazy.Value.ConfigureAwait(false); principalId ??= await principalIdLazy.Value.ConfigureAwait(false); - var task = provisoner.GetOrCreateResourceAsync(armClient, + var task = provisioner.GetOrCreateResourceAsync(armClient, subscription, resourceGroup, resourceMap, diff --git a/src/Aspire.Hosting.Azure.Provisioning/Provisioners/KeyVaultProvisoner.cs b/src/Aspire.Hosting.Azure.Provisioning/Provisioners/KeyVaultProvisoner.cs index 1e3de9cd98..c6ee059b3d 100644 --- a/src/Aspire.Hosting.Azure.Provisioning/Provisioners/KeyVaultProvisoner.cs +++ b/src/Aspire.Hosting.Azure.Provisioning/Provisioners/KeyVaultProvisoner.cs @@ -14,7 +14,7 @@ namespace Aspire.Hosting.Azure.Provisioning; -internal sealed class KeyVaultProvisoner(ILogger logger) : AzureResourceProvisioner +internal sealed class KeyVaultProvisioner(ILogger logger) : AzureResourceProvisioner { public override bool ConfigureResource(IConfiguration configuration, AzureKeyVaultResource resource) { @@ -76,7 +76,7 @@ public override async Task GetOrCreateResourceAsync( connectionStrings[keyVault.Name] = keyVault.VaultUri.ToString(); // Key Vault Administrator - // https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#key-vault-administrator + // https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#key-vault-administrator var roleDefinitionId = CreateRoleDefinitionId(subscription, "00482a5a-887f-4fb3-b363-3b7fe8e74483"); await DoRoleAssignmentAsync(armClient, keyVaultResource.Id, principalId, roleDefinitionId, cancellationToken).ConfigureAwait(false); diff --git a/src/Aspire.Hosting.Azure.Provisioning/Provisioners/ServiceBusProvisioner.cs b/src/Aspire.Hosting.Azure.Provisioning/Provisioners/ServiceBusProvisioner.cs index 36c35c3d5e..cf7fa4e6d6 100644 --- a/src/Aspire.Hosting.Azure.Provisioning/Provisioners/ServiceBusProvisioner.cs +++ b/src/Aspire.Hosting.Azure.Provisioning/Provisioners/ServiceBusProvisioner.cs @@ -150,7 +150,7 @@ public override async Task GetOrCreateResourceAsync( } // Azure Service Bus Data Owner - // https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#azure-service-bus-data-owner + // https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#azure-service-bus-data-owner var roleDefinitionId = CreateRoleDefinitionId(subscription, "090c5cfd-751d-490a-894a-3ce6f1109419"); await DoRoleAssignmentAsync(armClient, serviceBusNamespace.Id, principalId, roleDefinitionId, cancellationToken).ConfigureAwait(false); diff --git a/src/Aspire.Hosting.Azure.Provisioning/Provisioners/StorageProvisioner.cs b/src/Aspire.Hosting.Azure.Provisioning/Provisioners/StorageProvisioner.cs index 43e08adbf4..e01b3ba2fb 100644 --- a/src/Aspire.Hosting.Azure.Provisioning/Provisioners/StorageProvisioner.cs +++ b/src/Aspire.Hosting.Azure.Provisioning/Provisioners/StorageProvisioner.cs @@ -91,15 +91,15 @@ public override async Task GetOrCreateResourceAsync( resourceEntry["QueueUri"] = resource.QueueUri.ToString(); // Storage Queue Data Contributor - // https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#storage-queue-data-contributor + // https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#storage-queue-data-contributor var storageQueueDataContributorId = CreateRoleDefinitionId(subscription, "974c5e8b-45b9-4653-ba55-5f855dd0fb88"); // Storage Table Data Contributor - // https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#storage-table-data-contributor + // https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#storage-table-data-contributor var storageDataContributorId = CreateRoleDefinitionId(subscription, "0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3"); // Storage Blob Data Contributor - // https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#storage-blob-data-contributor + // https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#storage-blob-data-contributor var storageBlobDataContributorId = CreateRoleDefinitionId(subscription, "81a9662b-bebf-436f-a333-f67b29880f12"); var t0 = DoRoleAssignmentAsync(armClient, storageAccount.Id, principalId, storageQueueDataContributorId, cancellationToken); diff --git a/src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs b/src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs index 830fc93b3d..89df2ea9c6 100644 --- a/src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs +++ b/src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs @@ -5,6 +5,9 @@ namespace Aspire.Hosting.Azure; // Copied from https://github.com/dotnet/runtime/blob/213833ea99b79a4b494b2935e1ccb10b93cd4cbc/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PathHelper.cs +/// +/// Provides helper methods for working with user secrets in a location outside of source control. +/// public class UserSecretsPathHelper { internal const string SecretsFileName = "secrets.json"; diff --git a/src/Aspire.Hosting.Azure/AzureAppConfigurationResource.cs b/src/Aspire.Hosting.Azure/AzureAppConfigurationResource.cs index 94544a3d40..8389144070 100644 --- a/src/Aspire.Hosting.Azure/AzureAppConfigurationResource.cs +++ b/src/Aspire.Hosting.Azure/AzureAppConfigurationResource.cs @@ -3,9 +3,20 @@ namespace Aspire.Hosting.ApplicationModel; +/// +/// Represents an Azure App Configuration resource. +/// +/// The name of the resource. public class AzureAppConfigurationResource(string name) : Resource(name), IAzureResource, IResourceWithConnectionString { + /// + /// Gets or sets the endpoint for the Azure App Configuration resource. + /// public string? Endpoint { get; set; } + /// + /// Gets the connection string for the Azure App Configuration resource. + /// + /// The connection string for the Azure App Configuration resource. public string? GetConnectionString() => Endpoint; } diff --git a/src/Aspire.Hosting.Azure/AzureBlobStorageResource.cs b/src/Aspire.Hosting.Azure/AzureBlobStorageResource.cs new file mode 100644 index 0000000000..0e31384507 --- /dev/null +++ b/src/Aspire.Hosting.Azure/AzureBlobStorageResource.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Aspire.Hosting.ApplicationModel; + +/// +/// Represents a resource that is stored in Azure Blob Storage. +/// +/// The name of the resource. +/// The that the resource is stored in. +public class AzureBlobStorageResource(string name, AzureStorageResource storage) : Resource(name), + IAzureResource, + IResourceWithConnectionString, + IResourceWithParent +{ + /// + /// Gets the parent AzureStorageResource of this AzureBlobStorageResource. + /// + public AzureStorageResource Parent => storage; + + /// + /// Gets the connection string for the Azure Blob Storage resource. + /// + /// The connection string for the Azure Blob Storage resource. + public string? GetConnectionString() => Parent.GetBlobConnectionString(); +} diff --git a/src/Aspire.Hosting.Azure/AzureKeyVaultResource.cs b/src/Aspire.Hosting.Azure/AzureKeyVaultResource.cs index 153dbfa50e..0891caf2dd 100644 --- a/src/Aspire.Hosting.Azure/AzureKeyVaultResource.cs +++ b/src/Aspire.Hosting.Azure/AzureKeyVaultResource.cs @@ -3,9 +3,20 @@ namespace Aspire.Hosting.ApplicationModel; +/// +/// Represents an Azure Key Vault resource that can be deployed to an Azure resource group. +/// +/// The name of the resource. public class AzureKeyVaultResource(string name) : Resource(name), IAzureResource, IResourceWithConnectionString { + /// + /// Gets or sets the URI of the Azure Key Vault. + /// public Uri? VaultUri { get; set; } + /// + /// Gets the connection string for the Azure Key Vault resource. + /// + /// The connection string for the Azure Key Vault resource. public string? GetConnectionString() => VaultUri?.ToString(); } diff --git a/src/Aspire.Hosting.Azure/AzureQueueStorageResource.cs b/src/Aspire.Hosting.Azure/AzureQueueStorageResource.cs new file mode 100644 index 0000000000..0a00648ba6 --- /dev/null +++ b/src/Aspire.Hosting.Azure/AzureQueueStorageResource.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Aspire.Hosting.ApplicationModel; + +/// +/// Represents an Azure Queue Storage resource. +/// +/// The name of the resource. +/// The that the resource is stored in. +public class AzureQueueStorageResource(string name, AzureStorageResource storage) : Resource(name), + IAzureResource, + IResourceWithConnectionString, + IResourceWithParent +{ + /// + /// Gets the parent AzureStorageResource of this AzureQueueStorageResource. + /// + public AzureStorageResource Parent => storage; + + /// + /// Gets the connection string for the Azure Queue Storage resource. + /// + /// The connection string for the Azure Queue Storage resource. + public string? GetConnectionString() => Parent.GetQueueConnectionString(); +} diff --git a/src/Aspire.Hosting.Azure/AzureRedisResource.cs b/src/Aspire.Hosting.Azure/AzureRedisResource.cs index 07528c6ba5..7ef61a9371 100644 --- a/src/Aspire.Hosting.Azure/AzureRedisResource.cs +++ b/src/Aspire.Hosting.Azure/AzureRedisResource.cs @@ -3,9 +3,20 @@ namespace Aspire.Hosting.ApplicationModel; +/// +/// Represents an Azure Redis resource. +/// +/// The name of the resource. public class AzureRedisResource(string name) : Resource(name), IAzureResource, IResourceWithConnectionString { + /// + /// Gets or sets the connection string for the Azure Redis resource. + /// public string? ConnectionString { get; set; } + /// + /// Gets the connection string for the Azure Redis resource. + /// + /// The connection string for the Azure Redis resource. public string? GetConnectionString() => ConnectionString; } diff --git a/src/Aspire.Hosting.Azure/AzureResourceExtensions.cs b/src/Aspire.Hosting.Azure/AzureResourceExtensions.cs index 19249d8365..4626980992 100644 --- a/src/Aspire.Hosting.Azure/AzureResourceExtensions.cs +++ b/src/Aspire.Hosting.Azure/AzureResourceExtensions.cs @@ -7,6 +7,9 @@ namespace Aspire.Hosting; +/// +/// Provides extension methods for adding Azure resources to the application model. +/// public static class AzureResourceExtensions { /// diff --git a/src/Aspire.Hosting.Azure/AzureServiceBusResource.cs b/src/Aspire.Hosting.Azure/AzureServiceBusResource.cs index 5e2d5b0bc3..10c43260ec 100644 --- a/src/Aspire.Hosting.Azure/AzureServiceBusResource.cs +++ b/src/Aspire.Hosting.Azure/AzureServiceBusResource.cs @@ -3,13 +3,31 @@ namespace Aspire.Hosting.ApplicationModel; +/// +/// Represents an Azure Service Bus resource. +/// +/// The name of the resource. public class AzureServiceBusResource(string name) : Resource(name), IAzureResource, IResourceWithConnectionString { - // This is the full uri to the service bus namespace e.g namespace.servicebus.windows.net + /// + /// Gets or sets the Service Bus endpoint. This is the full uri to the service bus + /// namespace, for example "namespace.servicebus.windows.net". + /// public string? ServiceBusEndpoint { get; set; } + /// + /// Gets or sets the names of the queues associated with the Azure Service Bus resource. + /// public string[] QueueNames { get; set; } = []; + + /// + /// Gets or sets the names of the topics associated with the Azure Service Bus resource. + /// public string[] TopicNames { get; set; } = []; + /// + /// Gets the connection string for the Azure Service Bus endpoint. + /// + /// The connection string for the Azure Service Bus endpoint. public string? GetConnectionString() => ServiceBusEndpoint; } diff --git a/src/Aspire.Hosting.Azure/AzureStorageResource.cs b/src/Aspire.Hosting.Azure/AzureStorageResource.cs index f814f5a911..2f0b43602c 100644 --- a/src/Aspire.Hosting.Azure/AzureStorageResource.cs +++ b/src/Aspire.Hosting.Azure/AzureStorageResource.cs @@ -6,12 +6,30 @@ namespace Aspire.Hosting.ApplicationModel; +/// +/// Represents an Azure Storage resource. +/// +/// The name of the resource. public class AzureStorageResource(string name) : Resource(name), IAzureResource { + /// + /// Gets or sets the URI of the Azure Table Storage resource. + /// public Uri? TableUri { get; set; } + + /// + /// Gets or sets the URI of the Azure Storage queue. + /// public Uri? QueueUri { get; set; } + + /// + /// Gets or sets the URI of the blob. + /// public Uri? BlobUri { get; set; } + /// + /// Gets a value indicating whether the Azure Storage resource is running in the local emulator. + /// public bool IsEmulator => this.IsContainer(); internal string? GetTableConnectionString() => IsEmulator @@ -34,39 +52,9 @@ private int GetEmulatorPort(string endpointName) => ?? throw new DistributedApplicationException($"Azure storage resource does not have endpoint annotation with name '{endpointName}'."); } -public class AzureTableStorageResource(string name, AzureStorageResource storage) : Resource(name), - IAzureResource, - IResourceWithConnectionString, - IResourceWithParent -{ - public AzureStorageResource Parent => storage; - - public string? GetConnectionString() => Parent.GetTableConnectionString(); -} - -public class AzureBlobStorageResource(string name, AzureStorageResource storage) : Resource(name), - IAzureResource, - IResourceWithConnectionString, - IResourceWithParent -{ - public AzureStorageResource Parent => storage; - - public string? GetConnectionString() => Parent.GetBlobConnectionString(); -} - -public class AzureQueueStorageResource(string name, AzureStorageResource storage) : Resource(name), - IAzureResource, - IResourceWithConnectionString, - IResourceWithParent -{ - public AzureStorageResource Parent => storage; - - public string? GetConnectionString() => Parent.GetQueueConnectionString(); -} - static file class AzureStorageEmulatorConnectionString { - // Use defaults from https://learn.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string#connect-to-the-emulator-account-using-the-shortcut + // Use defaults from https://learn.microsoft.com/azure/storage/common/storage-configure-connection-string#connect-to-the-emulator-account-using-the-shortcut private const string ConnectionStringHeader = "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;"; private const string BlobEndpointTemplate = "BlobEndpoint=http://127.0.0.1:{0}/devstoreaccount1;"; private const string QueueEndpointTemplate = "QueueEndpoint=http://127.0.0.1:{0}/devstoreaccount1;"; diff --git a/src/Aspire.Hosting.Azure/AzureTableStorageResource.cs b/src/Aspire.Hosting.Azure/AzureTableStorageResource.cs new file mode 100644 index 0000000000..bf8d1313ab --- /dev/null +++ b/src/Aspire.Hosting.Azure/AzureTableStorageResource.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Aspire.Hosting.ApplicationModel; + +/// +/// Represents an Azure Table Storage resource. +/// +/// The name of the resource. +/// The that the resource is stored in. +public class AzureTableStorageResource(string name, AzureStorageResource storage) : Resource(name), + IAzureResource, + IResourceWithConnectionString, + IResourceWithParent +{ + /// + /// Gets the parent AzureStorageResource of this AzureTableStorageResource. + /// + public AzureStorageResource Parent => storage; + + /// + /// Gets the connection string for the Azure Table Storage resource. + /// + /// The connection string for the Azure Table Storage resource. + public string? GetConnectionString() => Parent.GetTableConnectionString(); +} diff --git a/src/Aspire.Hosting.Azure/IAzureResource.cs b/src/Aspire.Hosting.Azure/IAzureResource.cs index 09a777dd1c..09731722ef 100644 --- a/src/Aspire.Hosting.Azure/IAzureResource.cs +++ b/src/Aspire.Hosting.Azure/IAzureResource.cs @@ -3,7 +3,10 @@ namespace Aspire.Hosting.ApplicationModel; +/// +/// Represents an Azure resource, as a marker interface for 's +/// that can be deployed to an Azure resource group. +/// public interface IAzureResource : IResource { - } diff --git a/src/Aspire.Hosting/DistributedApplication.cs b/src/Aspire.Hosting/DistributedApplication.cs index a52e3aa25c..763e4116aa 100644 --- a/src/Aspire.Hosting/DistributedApplication.cs +++ b/src/Aspire.Hosting/DistributedApplication.cs @@ -120,7 +120,7 @@ private void SuppressLifetimeLogsDuringManifestPublishing() if (options.Value?.Publisher != "manifest") { - // If we aren't doing manifest pubilshing we want the logs + // If we aren't doing manifest publishing we want the logs // to be produced as normal. return; } @@ -171,4 +171,3 @@ private async Task ExecuteBeforeStartHooksAsync(CancellationToken cancellationTo Task IHost.StopAsync(CancellationToken cancellationToken) => StopAsync(cancellationToken); } - diff --git a/src/Components/Aspire.Azure.Data.Tables/AspireTablesExtensions.cs b/src/Components/Aspire.Azure.Data.Tables/AspireTablesExtensions.cs index 2049ea26a7..132240864f 100644 --- a/src/Components/Aspire.Azure.Data.Tables/AspireTablesExtensions.cs +++ b/src/Components/Aspire.Azure.Data.Tables/AspireTablesExtensions.cs @@ -14,6 +14,9 @@ namespace Microsoft.Extensions.Hosting; +/// +/// Provides extension methods for registering as a singleton in the services provided by the . +/// public static class AspireTablesExtensions { private const string DefaultConfigSectionName = "Aspire:Azure:Data:Tables"; diff --git a/src/Components/Aspire.Azure.Messaging.ServiceBus/AspireServiceBusExtensions.cs b/src/Components/Aspire.Azure.Messaging.ServiceBus/AspireServiceBusExtensions.cs index 7ec606c577..470746c30d 100644 --- a/src/Components/Aspire.Azure.Messaging.ServiceBus/AspireServiceBusExtensions.cs +++ b/src/Components/Aspire.Azure.Messaging.ServiceBus/AspireServiceBusExtensions.cs @@ -15,6 +15,9 @@ namespace Microsoft.Extensions.Hosting; +/// +/// Provides extension methods for registering as a singleton in the services provided by the . +/// public static class AspireServiceBusExtensions { private const string DefaultConfigSectionName = "Aspire:Azure:Messaging:ServiceBus"; diff --git a/src/Components/Aspire.Azure.Security.KeyVault/AspireKeyVaultExtensions.cs b/src/Components/Aspire.Azure.Security.KeyVault/AspireKeyVaultExtensions.cs index d2969a69a7..262148494e 100644 --- a/src/Components/Aspire.Azure.Security.KeyVault/AspireKeyVaultExtensions.cs +++ b/src/Components/Aspire.Azure.Security.KeyVault/AspireKeyVaultExtensions.cs @@ -16,6 +16,9 @@ namespace Microsoft.Extensions.Hosting; +/// +/// Provides extension methods for registering and configuring Azure Key Vault secrets in a .NET Aspire application. +/// public static class AspireKeyVaultExtensions { internal const string DefaultConfigSectionName = "Aspire:Azure:Security:KeyVault"; diff --git a/src/Components/Aspire.Azure.Storage.Blobs/AspireBlobStorageExtensions.cs b/src/Components/Aspire.Azure.Storage.Blobs/AspireBlobStorageExtensions.cs index cc6f011dcb..ec24d5b410 100644 --- a/src/Components/Aspire.Azure.Storage.Blobs/AspireBlobStorageExtensions.cs +++ b/src/Components/Aspire.Azure.Storage.Blobs/AspireBlobStorageExtensions.cs @@ -14,6 +14,9 @@ namespace Microsoft.Extensions.Hosting; +/// +/// Provides extension methods for registering as a singleton in the services provided by the . +/// public static class AspireBlobStorageExtensions { private const string DefaultConfigSectionName = "Aspire:Azure:Storage:Blobs"; diff --git a/src/Components/Aspire.Azure.Storage.Queues/AspireQueueStorageExtensions.cs b/src/Components/Aspire.Azure.Storage.Queues/AspireQueueStorageExtensions.cs index bf59f57ce5..cc57fec457 100644 --- a/src/Components/Aspire.Azure.Storage.Queues/AspireQueueStorageExtensions.cs +++ b/src/Components/Aspire.Azure.Storage.Queues/AspireQueueStorageExtensions.cs @@ -14,6 +14,10 @@ namespace Microsoft.Extensions.Hosting; +/// +/// Provides extension methods for registering as a singleton in the services provided by the . +/// Enables retries, corresponding health check, logging and telemetry. +/// public static class AspireQueueStorageExtensions { private const string DefaultConfigSectionName = "Aspire:Azure:Storage:Queues"; diff --git a/src/Components/Aspire.Microsoft.EntityFrameworkCore.SqlServer/AspireSqlServerEFCoreSqlClientExtensions.cs b/src/Components/Aspire.Microsoft.EntityFrameworkCore.SqlServer/AspireSqlServerEFCoreSqlClientExtensions.cs index 265725f4a6..1300e8f7c1 100644 --- a/src/Components/Aspire.Microsoft.EntityFrameworkCore.SqlServer/AspireSqlServerEFCoreSqlClientExtensions.cs +++ b/src/Components/Aspire.Microsoft.EntityFrameworkCore.SqlServer/AspireSqlServerEFCoreSqlClientExtensions.cs @@ -96,7 +96,7 @@ public static class AspireSqlServerEFCoreSqlClientExtensions void ConfigureDbContext(DbContextOptionsBuilder dbContextOptionsBuilder) { // We don't register logger factory, because there is no need to: - // https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontextoptionsbuilder.useloggerfactory?view=efcore-7.0#remarks + // https://learn.microsoft.com/dotnet/api/microsoft.entityframeworkcore.dbcontextoptionsbuilder.useloggerfactory?view=efcore-7.0#remarks dbContextOptionsBuilder.UseSqlServer(settings.ConnectionString, builder => { if (string.IsNullOrEmpty(settings.ConnectionString)) diff --git a/src/Components/Aspire.Microsoft.EntityFrameworkCore.SqlServer/README.md b/src/Components/Aspire.Microsoft.EntityFrameworkCore.SqlServer/README.md index 8120c362f1..438920592b 100644 --- a/src/Components/Aspire.Microsoft.EntityFrameworkCore.SqlServer/README.md +++ b/src/Components/Aspire.Microsoft.EntityFrameworkCore.SqlServer/README.md @@ -1,6 +1,6 @@ # Aspire.Microsoft.EntityFrameworkCore.SqlServer library -Registers [EntityFrameworkCore](https://learn.microsoft.com/en-us/ef/core/) [DbContext](https://learn.microsoft.com/dotnet/api/microsoft.entityframeworkcore.dbcontext) service for connecting Azure SQL, MS SQL server database. Enables connection pooling, health check, logging and telemetry. +Registers [EntityFrameworkCore](https://learn.microsoft.com/ef/core/) [DbContext](https://learn.microsoft.com/dotnet/api/microsoft.entityframeworkcore.dbcontext) service for connecting Azure SQL, MS SQL server database. Enables connection pooling, health check, logging and telemetry. ## Getting started diff --git a/src/Components/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL/AspireEFPostgreSqlExtensions.cs b/src/Components/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL/AspireEFPostgreSqlExtensions.cs index 6bb9e9c108..bfe9a02621 100644 --- a/src/Components/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL/AspireEFPostgreSqlExtensions.cs +++ b/src/Components/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL/AspireEFPostgreSqlExtensions.cs @@ -11,6 +11,9 @@ namespace Microsoft.Extensions.Hosting; +/// +/// Provides extension methods for registering a PostgreSQL database context in an Aspire application. +/// public static partial class AspireEFPostgreSqlExtensions { private const string DefaultConfigSectionName = "Aspire:Npgsql:EntityFrameworkCore:PostgreSQL"; @@ -114,7 +117,7 @@ public static partial class AspireEFPostgreSqlExtensions .WithMetrics(meterProviderBuilder => { // Currently EF provides only Event Counters: - // https://learn.microsoft.com/en-us/ef/core/logging-events-diagnostics/event-counters?tabs=windows#counters-and-their-meaning + // https://learn.microsoft.com/ef/core/logging-events-diagnostics/event-counters?tabs=windows#counters-and-their-meaning meterProviderBuilder.AddEventCountersInstrumentation(eventCountersInstrumentationOptions => { // The magic strings come from: @@ -130,7 +133,7 @@ public static partial class AspireEFPostgreSqlExtensions void ConfigureDbContext(DbContextOptionsBuilder dbContextOptionsBuilder) { // We don't provide the connection string, it's going to use the pre-registered DataSource. - // We don't register logger factory, because there is no need to: https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontextoptionsbuilder.useloggerfactory?view=efcore-7.0#remarks + // We don't register logger factory, because there is no need to: https://learn.microsoft.com/dotnet/api/microsoft.entityframeworkcore.dbcontextoptionsbuilder.useloggerfactory?view=efcore-7.0#remarks dbContextOptionsBuilder.UseNpgsql(builder => { // Resiliency: diff --git a/src/Components/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL/README.md b/src/Components/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL/README.md index 6217b35dee..e42d509233 100644 --- a/src/Components/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL/README.md +++ b/src/Components/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL/README.md @@ -1,6 +1,6 @@ # Aspire.Npgsql.EntityFrameworkCore.PostgreSQL library -Registers [EntityFrameworkCore](https://learn.microsoft.com/en-us/ef/core/) [DbContext](https://learn.microsoft.com/dotnet/api/microsoft.entityframeworkcore.dbcontext) in the DI container for connecting PostgreSQL®* database. Enables connection pooling, health check, logging and telemetry. +Registers [EntityFrameworkCore](https://learn.microsoft.com/ef/core/) [DbContext](https://learn.microsoft.com/dotnet/api/microsoft.entityframeworkcore.dbcontext) in the DI container for connecting PostgreSQL®* database. Enables connection pooling, health check, logging and telemetry. ## Getting started diff --git a/src/Components/Aspire.StackExchange.Redis.DistributedCaching/AspireRedisDistributedCacheExtensions.cs b/src/Components/Aspire.StackExchange.Redis.DistributedCaching/AspireRedisDistributedCacheExtensions.cs index f8f2edca3c..561c310c54 100644 --- a/src/Components/Aspire.StackExchange.Redis.DistributedCaching/AspireRedisDistributedCacheExtensions.cs +++ b/src/Components/Aspire.StackExchange.Redis.DistributedCaching/AspireRedisDistributedCacheExtensions.cs @@ -9,6 +9,9 @@ namespace Microsoft.Extensions.Hosting; +/// +/// Provides extension methods for adding Redis distributed caching services to an . +/// public static class AspireRedisDistributedCacheExtensions { /// diff --git a/src/Components/Aspire.StackExchange.Redis.OutputCaching/AspireRedisOutputCacheExtensions.cs b/src/Components/Aspire.StackExchange.Redis.OutputCaching/AspireRedisOutputCacheExtensions.cs index e2a1bc391b..f900bbdb69 100644 --- a/src/Components/Aspire.StackExchange.Redis.OutputCaching/AspireRedisOutputCacheExtensions.cs +++ b/src/Components/Aspire.StackExchange.Redis.OutputCaching/AspireRedisOutputCacheExtensions.cs @@ -8,6 +8,9 @@ namespace Microsoft.Extensions.Hosting; +/// +/// Provides extension methods for adding Redis output caching services to the . +/// public static class AspireRedisOutputCacheExtensions { /// diff --git a/src/Components/Aspire.StackExchange.Redis/AspireRedisExtensions.cs b/src/Components/Aspire.StackExchange.Redis/AspireRedisExtensions.cs index 4d7731ed9d..22e0c91ab6 100644 --- a/src/Components/Aspire.StackExchange.Redis/AspireRedisExtensions.cs +++ b/src/Components/Aspire.StackExchange.Redis/AspireRedisExtensions.cs @@ -16,6 +16,9 @@ namespace Microsoft.Extensions.Hosting; +/// +/// Provides extension methods for registering Redis-related services in an . +/// public static class AspireRedisExtensions { private const string DefaultConfigSectionName = "Aspire:StackExchange:Redis"; diff --git a/src/Microsoft.Extensions.ServiceDiscovery.Abstractions/Features/IEndPointHealthFeature.cs b/src/Microsoft.Extensions.ServiceDiscovery.Abstractions/Features/IEndPointHealthFeature.cs index 50276e05ec..63dc3e11a3 100644 --- a/src/Microsoft.Extensions.ServiceDiscovery.Abstractions/Features/IEndPointHealthFeature.cs +++ b/src/Microsoft.Extensions.ServiceDiscovery.Abstractions/Features/IEndPointHealthFeature.cs @@ -3,10 +3,16 @@ namespace Microsoft.Extensions.ServiceDiscovery.Abstractions; +/// +/// Represents a feature that reports the health of an endpoint, for use in triggering internal cache refresh and for use in load balancing. +/// public interface IEndPointHealthFeature { - // Reports health of the endpoint, for use in triggering internal cache refresh and for use in load balancing. - // Can be a no-op. + /// + /// Reports health of the endpoint, for use in triggering internal cache refresh and for use in load balancing. Can be a no-op. + /// + /// The response time of the endpoint. + /// An optional exception that occurred while checking the endpoint's health. void ReportHealth(TimeSpan responseTime, Exception? exception); } diff --git a/src/Microsoft.Extensions.ServiceDiscovery.Abstractions/Features/IEndPointLoadFeature.cs b/src/Microsoft.Extensions.ServiceDiscovery.Abstractions/Features/IEndPointLoadFeature.cs index d58f23c777..2610f13594 100644 --- a/src/Microsoft.Extensions.ServiceDiscovery.Abstractions/Features/IEndPointLoadFeature.cs +++ b/src/Microsoft.Extensions.ServiceDiscovery.Abstractions/Features/IEndPointLoadFeature.cs @@ -3,9 +3,14 @@ namespace Microsoft.Extensions.ServiceDiscovery.Abstractions; +/// +/// Represents a feature that provides information about the current load of an endpoint. +/// public interface IEndPointLoadFeature { - // CurrentLoad is some comparable measure of load (queue length, concurrent requests, etc) + /// + /// Gets a comparable measure of the current load of the endpoint (e.g. queue length, concurrent requests, etc). + /// public double CurrentLoad { get; } } From 77805c866c028ec931a7c159672931afb4dce113 Mon Sep 17 00:00:00 2001 From: David Pine Date: Thu, 2 Nov 2023 10:15:24 -0500 Subject: [PATCH 2/4] Revert Aspire.sln change --- Aspire.sln | 3 --- 1 file changed, 3 deletions(-) diff --git a/Aspire.sln b/Aspire.sln index 4e351b8598..5647600b1a 100644 --- a/Aspire.sln +++ b/Aspire.sln @@ -137,9 +137,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CatalogDb", "samples\eShopL EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{991DB378-6CB5-4441-BFC3-657400690FC3}" ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - Directory.Build.props = Directory.Build.props - Directory.Build.targets = Directory.Build.targets Directory.Packages.props = Directory.Packages.props EndProjectSection EndProject From 3f2ca51d115729e28007c063863cb99f462903bc Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 2 Nov 2023 08:44:59 -0700 Subject: [PATCH 3/4] Update src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs --- src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs b/src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs index 89df2ea9c6..b968ac04a6 100644 --- a/src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs +++ b/src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs @@ -8,7 +8,7 @@ namespace Aspire.Hosting.Azure; /// /// Provides helper methods for working with user secrets in a location outside of source control. /// -public class UserSecretsPathHelper +internal class UserSecretsPathHelper { internal const string SecretsFileName = "secrets.json"; From 75a832427a1aebc289db8883dd0b94d25b744e21 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 2 Nov 2023 08:50:56 -0700 Subject: [PATCH 4/4] Update src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs --- src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs b/src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs index b968ac04a6..66b67299a2 100644 --- a/src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs +++ b/src/Aspire.Hosting.Azure.Provisioning/UserSecretsPathHelper.cs @@ -8,7 +8,7 @@ namespace Aspire.Hosting.Azure; /// /// Provides helper methods for working with user secrets in a location outside of source control. /// -internal class UserSecretsPathHelper +internal sealed class UserSecretsPathHelper { internal const string SecretsFileName = "secrets.json";