| File: ApplicationModel\ConnectionStringReference.cs | Web Access |
| Project: src\src\Aspire.Hosting\Aspire.Hosting.csproj (Aspire.Hosting) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; namespace Aspire.Hosting.ApplicationModel; /// <summary> /// Represents a reference to a connection string. /// </summary> public class ConnectionStringReference(IResourceWithConnectionString resource, bool optional) : IExpressionValue, IManifestExpressionProvider, IValueProvider, IValueWithReferences { private readonly ReferenceExpression? _connectionStringExpression; #pragma warning disable ASPIRECONNECTIONSTRINGS001 internal ConnectionStringReference( IResourceWithConnectionString resource, bool optional, ConnectionStringEnvironmentVariableNames environmentVariableNames, string valueName, ReferenceExpression? connectionStringExpression) : this(resource, optional) { EnvironmentVariableNames = environmentVariableNames ?? throw new ArgumentNullException(nameof(environmentVariableNames)); ValueName = valueName ?? throw new ArgumentNullException(nameof(valueName)); _connectionStringExpression = connectionStringExpression; } #pragma warning restore ASPIRECONNECTIONSTRINGS001 /// <summary> /// The resource that the connection string is referencing. /// </summary> public IResourceWithConnectionString Resource { get; } = resource ?? throw new ArgumentNullException(nameof(resource)); /// <summary> /// A flag indicating whether the connection string is optional. /// </summary> public bool Optional { get; } = optional; /// <summary> /// Gets the logical and physical environment-variable names when this reference represents /// a generated connection-string injection, or <see langword="null"/> for a standalone value reference. /// </summary> [Experimental("ASPIRECONNECTIONSTRINGS001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")] public ConnectionStringEnvironmentVariableNames? EnvironmentVariableNames { get; } /// <summary> /// Gets the expression for the referenced connection-string value. /// </summary> /// <remarks> /// Uses the resource's current connection-string expression unless the reference selects /// another connection-string value, such as an HTTP connection on a resource with multiple protocols. /// </remarks> public ReferenceExpression ConnectionStringExpression => _connectionStringExpression ?? Resource.ConnectionStringExpression; // Alias equivalence must not depend on mutable expression text or last-wins optionality. internal string ValueName { get; } = nameof(IResourceWithConnectionString.ConnectionStringExpression); string IManifestExpressionProvider.ValueExpression => _connectionStringExpression?.ValueExpression ?? Resource.ValueExpression; IEnumerable<object> IValueWithReferences.References => _connectionStringExpression is { } expression ? [Resource, expression] : [Resource]; ValueTask<string?> IValueProvider.GetValueAsync(CancellationToken cancellationToken) { return _connectionStringExpression is { } expression ? expression.GetValueAsync(cancellationToken) : Resource.GetValueAsync(cancellationToken); } async ValueTask<string?> IValueProvider.GetValueAsync(ValueProviderContext context, CancellationToken cancellationToken) { var value = _connectionStringExpression is { } expression ? await expression.GetValueAsync(context, cancellationToken).ConfigureAwait(false) : await Resource.GetValueAsync(context, cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(value) && !Optional) { ThrowConnectionStringUnavailableException(); } return value; } internal void ThrowConnectionStringUnavailableException() => throw new DistributedApplicationException($"The connection string for the resource '{Resource.Name}' is not available."); }