diff --git a/src/Aspire.Dashboard/Aspire.Dashboard.csproj b/src/Aspire.Dashboard/Aspire.Dashboard.csproj
index f4e6f2fe6d..95e61ea584 100644
--- a/src/Aspire.Dashboard/Aspire.Dashboard.csproj
+++ b/src/Aspire.Dashboard/Aspire.Dashboard.csproj
@@ -170,7 +170,7 @@
Protos\resource_service.proto
-
+
diff --git a/src/Aspire.Dashboard/DashboardWebApplication.cs b/src/Aspire.Dashboard/DashboardWebApplication.cs
index 8c037beca8..01caf989f1 100644
--- a/src/Aspire.Dashboard/DashboardWebApplication.cs
+++ b/src/Aspire.Dashboard/DashboardWebApplication.cs
@@ -29,13 +29,9 @@ public DashboardWebApplication()
builder.Logging.AddFilter("Microsoft.Hosting.Lifetime", LogLevel.None);
builder.Logging.AddFilter("Microsoft.AspNetCore.Server.Kestrel", LogLevel.Error);
- var environmentVariables = new EnvironmentVariables();
+ var dashboardUris = builder.Configuration.GetUris(DashboardUrlVariableName, new(DashboardUrlDefaultValue));
- builder.Services.AddSingleton(environmentVariables);
-
- var dashboardUris = environmentVariables.GetUris(DashboardUrlVariableName, new(DashboardUrlDefaultValue));
-
- var otlpUris = environmentVariables.GetUris(DashboardOtlpUrlVariableName, new(DashboardOtlpUrlDefaultValue));
+ var otlpUris = builder.Configuration.GetUris(DashboardOtlpUrlVariableName, new(DashboardOtlpUrlDefaultValue));
if (otlpUris.Length > 1)
{
diff --git a/src/Aspire.Dashboard/Model/DashboardClient.cs b/src/Aspire.Dashboard/Model/DashboardClient.cs
index c85679e834..726ba61d70 100644
--- a/src/Aspire.Dashboard/Model/DashboardClient.cs
+++ b/src/Aspire.Dashboard/Model/DashboardClient.cs
@@ -39,7 +39,7 @@ internal sealed class DashboardClient : IDashboardClient
private readonly object _lock = new();
private readonly ILoggerFactory _loggerFactory;
- private readonly IEnvironmentVariables _environmentVariables;
+ private readonly IConfiguration _configuration;
private readonly ILogger _logger;
private ImmutableHashSet> _outgoingChannels = [];
@@ -56,14 +56,14 @@ internal sealed class DashboardClient : IDashboardClient
private Task? _connection;
- public DashboardClient(ILoggerFactory loggerFactory, IEnvironmentVariables environmentVariables)
+ public DashboardClient(ILoggerFactory loggerFactory, IConfiguration configuration)
{
_loggerFactory = loggerFactory;
- _environmentVariables = environmentVariables;
+ _configuration = configuration;
_logger = loggerFactory.CreateLogger();
- var address = environmentVariables.GetUri(ResourceServiceUrlVariableName);
+ var address = configuration.GetUri(ResourceServiceUrlVariableName);
if (address is null)
{
@@ -307,7 +307,7 @@ Task IDashboardClient.WhenConnected
string IDashboardClient.ApplicationName
{
get => _applicationName
- ?? _environmentVariables.GetString("DOTNET_DASHBOARD_APPLICATION_NAME")
+ ?? _configuration["DOTNET_DASHBOARD_APPLICATION_NAME"]
?? "Aspire";
}
diff --git a/src/Aspire.Hosting/Aspire.Hosting.csproj b/src/Aspire.Hosting/Aspire.Hosting.csproj
index bfd45d100d..a71622b038 100644
--- a/src/Aspire.Hosting/Aspire.Hosting.csproj
+++ b/src/Aspire.Hosting/Aspire.Hosting.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/src/Aspire.Hosting/Dashboard/DashboardServiceData.cs b/src/Aspire.Hosting/Dashboard/DashboardServiceData.cs
index fd45b85558..fcbde72f34 100644
--- a/src/Aspire.Hosting/Dashboard/DashboardServiceData.cs
+++ b/src/Aspire.Hosting/Dashboard/DashboardServiceData.cs
@@ -4,6 +4,7 @@
using System.Runtime.CompilerServices;
using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.Dcp;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Aspire.Hosting.Dashboard;
@@ -21,13 +22,13 @@ internal sealed class DashboardServiceData : IAsyncDisposable
public DashboardServiceData(
DistributedApplicationModel applicationModel,
KubernetesService kubernetesService,
- IEnvironmentVariables environmentVariables,
+ IConfiguration configuration,
ILoggerFactory loggerFactory)
{
_resourcePublisher = new ResourcePublisher(_cts.Token);
_consoleLogPublisher = new ConsoleLogPublisher(_resourcePublisher);
- _ = new DcpDataSource(kubernetesService, applicationModel, environmentVariables, loggerFactory, _resourcePublisher.IntegrateAsync, _cts.Token);
+ _ = new DcpDataSource(kubernetesService, applicationModel, configuration, loggerFactory, _resourcePublisher.IntegrateAsync, _cts.Token);
}
public async ValueTask DisposeAsync()
diff --git a/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs b/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs
index 9626817c5c..48f609b247 100644
--- a/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs
+++ b/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs
@@ -10,6 +10,7 @@
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Server.Kestrel.Core;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Internal;
@@ -49,7 +50,7 @@ public DashboardServiceHost(
DistributedApplicationOptions options,
DistributedApplicationModel applicationModel,
KubernetesService kubernetesService,
- IEnvironmentVariables environmentVariables,
+ IConfiguration configuration,
IOptions publishingOptions,
ILoggerFactory loggerFactory,
IConfigureOptions loggerOptions)
@@ -68,8 +69,8 @@ public DashboardServiceHost(
{
var builder = WebApplication.CreateBuilder();
- // Environment
- builder.Services.AddSingleton();
+ // Configuration
+ builder.Services.AddSingleton(configuration);
// Logging
builder.Services.AddSingleton(loggerFactory);
@@ -98,7 +99,7 @@ public DashboardServiceHost(
void ConfigureKestrel(KestrelServerOptions kestrelOptions)
{
// Inspect environment for the address to listen on.
- var uri = environmentVariables.GetUri(ResourceServiceUrlVariableName);
+ var uri = configuration.GetUri(ResourceServiceUrlVariableName);
string? scheme;
diff --git a/src/Aspire.Hosting/Dashboard/DcpDataSource.cs b/src/Aspire.Hosting/Dashboard/DcpDataSource.cs
index b4aa80b385..f357967d0a 100644
--- a/src/Aspire.Hosting/Dashboard/DcpDataSource.cs
+++ b/src/Aspire.Hosting/Dashboard/DcpDataSource.cs
@@ -8,6 +8,7 @@
using Aspire.Hosting.Dcp;
using Aspire.Hosting.Dcp.Model;
using k8s;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Aspire.Hosting.Dashboard;
@@ -35,7 +36,7 @@ internal sealed class DcpDataSource
public DcpDataSource(
KubernetesService kubernetesService,
DistributedApplicationModel applicationModel,
- IEnvironmentVariables environmentVariables,
+ IConfiguration configuration,
ILoggerFactory loggerFactory,
Func onResourceChanged,
CancellationToken cancellationToken)
@@ -96,7 +97,7 @@ bool IsFilteredResource(T resource) where T : CustomResource
// We filter out any resources that start with aspire-dashboard (there are services as well as executables).
if (resource.Metadata.Name.StartsWith(KnownResourceNames.AspireDashboard, StringComparisons.ResourceName))
{
- return environmentVariables.GetBool("DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES") is not true;
+ return configuration.GetBool("DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES") is not true;
}
return false;
diff --git a/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs b/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs
index 7dbd588519..f70069fcf6 100644
--- a/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs
+++ b/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs
@@ -8,6 +8,7 @@
using Aspire.Hosting.Lifecycle;
using Aspire.Hosting.Utils;
using k8s;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@@ -55,7 +56,7 @@ internal sealed class ApplicationExecutor(ILogger logger,
DistributedApplicationOptions distributedApplicationOptions,
KubernetesService kubernetesService,
IEnumerable lifecycleHooks,
- IEnvironmentVariables environmentVariables,
+ IConfiguration configuration,
IOptions options,
DashboardServiceHost dashboardHost)
{
@@ -137,12 +138,12 @@ private async Task ConfigureAspireDashboardResource(IResource dashboardResource,
dashboardResource.Annotations.Add(new EnvironmentCallbackAnnotation(context =>
{
- if (Environment.GetEnvironmentVariable("ASPNETCORE_URLS") is not { } appHostApplicationUrl)
+ if (configuration["ASPNETCORE_URLS"] is not { } appHostApplicationUrl)
{
throw new DistributedApplicationException("Failed to configure dashboard resource because ASPNETCORE_URLS environment variable was not set.");
}
- if (Environment.GetEnvironmentVariable("DOTNET_DASHBOARD_OTLP_ENDPOINT_URL") is not { } otlpEndpointUrl)
+ if (configuration["DOTNET_DASHBOARD_OTLP_ENDPOINT_URL"] is not { } otlpEndpointUrl)
{
throw new DistributedApplicationException("Failed to configure dashboard resource because DOTNET_DASHBOARD_OTLP_ENDPOINT_URL environment variable was not set.");
}
@@ -202,9 +203,9 @@ private async Task StartDashboardAsDcpExecutableAsync(CancellationToken cancella
// Matches DashboardWebApplication.DashboardUrlDefaultValue
const string defaultDashboardUrl = "http://localhost:18888";
- var otlpEndpointUrl = environmentVariables.GetString("DOTNET_DASHBOARD_OTLP_ENDPOINT_URL");
- var dashboardUrls = environmentVariables.GetString("ASPNETCORE_URLS") ?? defaultDashboardUrl;
- var aspnetcoreEnvironment = environmentVariables.GetString("ASPNETCORE_ENVIRONMENT");
+ var otlpEndpointUrl = configuration["DOTNET_DASHBOARD_OTLP_ENDPOINT_URL"];
+ var dashboardUrls = configuration["ASPNETCORE_URLS"] ?? defaultDashboardUrl;
+ var aspnetcoreEnvironment = configuration["ASPNETCORE_ENVIRONMENT"];
dashboardExecutableSpec.Env =
[
@@ -239,11 +240,11 @@ private async Task StartDashboardAsDcpExecutableAsync(CancellationToken cancella
await CheckDashboardAvailabilityAsync(dashboardUrls, cancellationToken).ConfigureAwait(false);
}
- private static TimeSpan DashboardAvailabilityTimeoutDuration
+ private TimeSpan DashboardAvailabilityTimeoutDuration
{
get
{
- if (Environment.GetEnvironmentVariable("DOTNET_ASPIRE_DASHBOARD_TIMEOUT_SECONDS") is { } timeoutString && int.TryParse(timeoutString, out var timeoutInSeconds))
+ if (configuration["DOTNET_ASPIRE_DASHBOARD_TIMEOUT_SECONDS"] is { } timeoutString && int.TryParse(timeoutString, out var timeoutInSeconds))
{
return TimeSpan.FromSeconds(timeoutInSeconds);
}
@@ -492,7 +493,7 @@ private void PrepareProjectExecutables()
annotationHolder.Annotate(Executable.CSharpProjectPathAnnotation, projectMetadata.ProjectPath);
annotationHolder.Annotate(Executable.OtelServiceNameAnnotation, ers.Metadata.Name);
- if (!string.IsNullOrEmpty(environmentVariables.GetString(DebugSessionPortVar)))
+ if (!string.IsNullOrEmpty(configuration[DebugSessionPortVar]))
{
exeSpec.ExecutionType = ExecutionType.IDE;
if (project.TryGetLastAnnotation(out var lpa))
@@ -503,7 +504,7 @@ private void PrepareProjectExecutables()
else
{
exeSpec.ExecutionType = ExecutionType.Process;
- if (environmentVariables.GetBool("DOTNET_WATCH") is true)
+ if (configuration.GetBool("DOTNET_WATCH") is true)
{
exeSpec.Args = [
"run",
@@ -657,7 +658,7 @@ private async Task CreateExecutablesAsync(IEnumerable executableRes
{
// We just check the HTTP endpoint because this will prove that the
// dashboard is listening and is ready to process requests.
- if (Environment.GetEnvironmentVariable("ASPNETCORE_URLS") is not { } dashboardUrls)
+ if (configuration["ASPNETCORE_URLS"] is not { } dashboardUrls)
{
throw new DistributedApplicationException("Cannot check dashboard availability since ASPNETCORE_URLS environment variable not set.");
}
diff --git a/src/Aspire.Hosting/DistributedApplicationBuilder.cs b/src/Aspire.Hosting/DistributedApplicationBuilder.cs
index ade2d8a365..1409f4a97e 100644
--- a/src/Aspire.Hosting/DistributedApplicationBuilder.cs
+++ b/src/Aspire.Hosting/DistributedApplicationBuilder.cs
@@ -61,7 +61,6 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options)
_innerBuilder.Services.AddHostedService();
_innerBuilder.Services.AddHostedService();
_innerBuilder.Services.AddSingleton(options);
- _innerBuilder.Services.AddSingleton();
// Dashboard
_innerBuilder.Services.AddSingleton();
diff --git a/src/Shared/IConfigurationExtensions.cs b/src/Shared/IConfigurationExtensions.cs
new file mode 100644
index 0000000000..768d3dcac8
--- /dev/null
+++ b/src/Shared/IConfigurationExtensions.cs
@@ -0,0 +1,121 @@
+// 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;
+using Microsoft.Extensions.Configuration;
+
+namespace Aspire;
+
+internal static class IConfigurationExtensions
+{
+ ///
+ /// Gets the named configuration value as a boolean.
+ ///
+ ///
+ /// Parses true and false, along with integer values (where non-zero is ).
+ ///
+ /// The this method extends.
+ /// The configuration key.
+ /// The parsed value, or if no value exists or it couldn't be parsed.
+ public static bool? GetBool(this IConfiguration configuration, string key)
+ {
+ var value = configuration[key];
+
+ if (value is null or [])
+ {
+ return null;
+ }
+ else if (bool.TryParse(value, out var b))
+ {
+ return b;
+ }
+ else if (int.TryParse(value, out var i))
+ {
+ return i != 0;
+ }
+
+ return null;
+ }
+
+ ///
+ /// Gets the named configuration value as a boolean.
+ ///
+ ///
+ /// Parses true and false, along with 1 and 0.
+ ///
+ /// The this method extends.
+ /// The configuration key.
+ /// A default value, for when the configuration value is unspecified or white space.
+ ///
+ public static bool GetBool(this IConfiguration configuration, string key, bool defaultValue)
+ {
+ return configuration.GetBool(key) ?? defaultValue;
+ }
+
+ ///
+ /// Parses a configuration value into a object.
+ ///
+ /// The this method extends.
+ /// The configuration key.
+ /// A default value, for when the configuration value is unspecified or white space. May be .
+ /// The parsed value, or the default value if specified and parsing failed. Returns if is and parsing failed.
+ /// The configuration value could not be accessed, or contained incorrectly formatted data.
+ [return: NotNullIfNotNull(nameof(defaultValue))]
+ public static Uri? GetUri(this IConfiguration configuration, string key, Uri? defaultValue = null)
+ {
+ try
+ {
+ var uri = configuration[key];
+
+ if (string.IsNullOrWhiteSpace(uri))
+ {
+ return defaultValue;
+ }
+ else
+ {
+ return new Uri(uri, UriKind.Absolute);
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new InvalidOperationException($"Error parsing URIs from configuration value '{key}'.", ex);
+ }
+ }
+
+ ///
+ /// Parses a configuration value's semicolon-delimited value into an array of objects.
+ ///
+ /// The this method extends.
+ /// The configuration key.
+ /// A default value, for when the configuration value is unspecified or white space. May be .
+ /// The parsed values, or the default value if specified and parsing failed. Returns if is and parsing failed.
+ /// The configuration value could not be accessed, or contained incorrectly formatted data.
+ [return: NotNullIfNotNull(nameof(defaultValue))]
+ public static Uri[]? GetUris(this IConfiguration configuration, string key, Uri? defaultValue = null)
+ {
+ try
+ {
+ var uris = configuration[key];
+
+ if (string.IsNullOrWhiteSpace(uris))
+ {
+ return defaultValue switch
+ {
+ not null => [defaultValue],
+ null => null
+ };
+ }
+ else
+ {
+ return uris
+ .Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
+ .Select(url => new Uri(url, UriKind.Absolute))
+ .ToArray();
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new InvalidOperationException($"Error parsing URIs from configuration value '{key}'.", ex);
+ }
+ }
+}
diff --git a/src/Shared/IEnvironmentVariables.cs b/src/Shared/IEnvironmentVariables.cs
deleted file mode 100644
index 66bd65f345..0000000000
--- a/src/Shared/IEnvironmentVariables.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Collections.Immutable;
-using System.Diagnostics.CodeAnalysis;
-
-namespace Aspire;
-
-///
-/// An abstraction over the current process's environment variables.
-///
-internal interface IEnvironmentVariables
-{
- ///
- /// Gets the named environment variable's value, or .
- ///
- /// The name of the environment variable.
- /// An optional default value to return if the environment variable is not present.
- /// The named environment variable's value if present, or if the variable is not present and no default was specified.
- [return: NotNullIfNotNull(nameof(defaultValue))]
- string? GetString(string variableName, string? defaultValue = null);
-}
-
-internal sealed class EnvironmentVariables : IEnvironmentVariables
-{
- ///
- /// A cache of all queried environment variables.
- ///
- private ImmutableDictionary _valueByName = ImmutableDictionary.Empty.WithComparers(StringComparers.EnvironmentVariableName);
-
- [return: NotNullIfNotNull(nameof(defaultValue))]
- public string? GetString(string variableName, string? defaultValue = null)
- {
- // Environment.GetEnvironmentVariable queries the variable each time,
- // but our variables don't change during the lifetime of the process.
- // So we cache them for faster repeat lookup.
- var value = ImmutableInterlocked.GetOrAdd(ref _valueByName, key: variableName, valueFactory: Environment.GetEnvironmentVariable);
-
- return value ?? defaultValue;
- }
-}
-
-internal static class IEnvironmentVariablesExtensions
-{
- ///
- /// Gets the named environment variable's value as a boolean.
- ///
- ///
- /// Parses true and false, along with integer values (where non-zero is ).
- ///
- /// The this method extends.
- /// The name of the environment variable.
- /// The parsed value, or if no value exists or it couldn't be parsed.
- public static bool? GetBool(this IEnvironmentVariables env, string variableName)
- {
- var str = env.GetString(variableName);
-
- if (str is null or [])
- {
- return null;
- }
- else if (bool.TryParse(str, out var b))
- {
- return b;
- }
- else if (int.TryParse(str, out var i))
- {
- return i != 0;
- }
-
- return null;
- }
-
- ///
- /// Gets the named environment variable's value as a boolean.
- ///
- ///
- /// Parses true and false, along with 1 and 0.
- ///
- /// The this method extends.
- /// The name of the environment variable.
- /// A default value, for when the environment variable is unspecified or white space.
- ///
- public static bool GetBool(this IEnvironmentVariables env, string variableName, bool defaultValue)
- {
- return env.GetBool(variableName) ?? defaultValue;
- }
-
- ///
- /// Parses a environment variable's value into a object.
- ///
- /// The this method extends.
- /// The name of the environment variable.
- /// A default value, for when the environment variable is unspecified or white space. May be .
- /// The parsed value, or the default value if specified and parsing failed. Returns if is and parsing failed.
- /// The environment variable could not be accessed, or contained incorrectly formatted data.
- [return: NotNullIfNotNull(nameof(defaultValue))]
- public static Uri? GetUri(this IEnvironmentVariables env, string variableName, Uri? defaultValue = null)
- {
- try
- {
- var uri = env.GetString(variableName);
-
- if (string.IsNullOrWhiteSpace(uri))
- {
- return defaultValue;
- }
- else
- {
- return new Uri(uri, UriKind.Absolute);
- }
- }
- catch (Exception ex)
- {
- throw new InvalidOperationException($"Error parsing URIs from environment variable '{variableName}'.", ex);
- }
- }
-
- ///
- /// Parses a environment variable's semicolon-delimited value into an array of objects.
- ///
- /// The this method extends.
- /// The name of the environment variable.
- /// A default value, for when the environment variable is unspecified or white space. May be .
- /// The parsed values, or the default value if specified and parsing failed. Returns if is and parsing failed.
- /// The environment variable could not be accessed, or contained incorrectly formatted data.
- [return: NotNullIfNotNull(nameof(defaultValue))]
- public static Uri[]? GetUris(this IEnvironmentVariables env, string variableName, Uri? defaultValue = null)
- {
- try
- {
- var uris = env.GetString(variableName);
-
- if (string.IsNullOrWhiteSpace(uris))
- {
- return defaultValue switch
- {
- not null => [defaultValue],
- null => null
- };
- }
- else
- {
- return uris
- .Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
- .Select(url => new Uri(url, UriKind.Absolute))
- .ToArray();
- }
- }
- catch (Exception ex)
- {
- throw new InvalidOperationException($"Error parsing URIs from environment variable '{variableName}'.", ex);
- }
- }
-}
diff --git a/tests/Aspire.Dashboard.Tests/MockEnvironmentVariables.cs b/tests/Aspire.Dashboard.Tests/MockEnvironmentVariables.cs
deleted file mode 100644
index 2584e13922..0000000000
--- a/tests/Aspire.Dashboard.Tests/MockEnvironmentVariables.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Collections;
-using System.Diagnostics.CodeAnalysis;
-
-namespace Aspire;
-
-internal sealed class MockEnvironmentVariables : IEnvironmentVariables, IEnumerable
-{
- private readonly Dictionary _valueByName = new(StringComparers.EnvironmentVariableName);
-
- public void Add(string name, string value)
- {
- _valueByName[name] = value;
- }
-
- [return: NotNullIfNotNull(nameof(defaultValue))]
- public string? GetString(string variableName, string? defaultValue = null)
- {
- if (_valueByName.TryGetValue(variableName, out var value))
- {
- return value;
- }
-
- return defaultValue;
- }
-
- IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
-}
diff --git a/tests/Aspire.Dashboard.Tests/Model/DashboardClientTests.cs b/tests/Aspire.Dashboard.Tests/Model/DashboardClientTests.cs
index 6914f1ea9d..39fe560401 100644
--- a/tests/Aspire.Dashboard.Tests/Model/DashboardClientTests.cs
+++ b/tests/Aspire.Dashboard.Tests/Model/DashboardClientTests.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using Aspire.Dashboard.Model;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging.Abstractions;
using Xunit;
@@ -9,12 +10,19 @@ namespace Aspire.Dashboard.Tests.Model;
public sealed class DashboardClientTests
{
- private readonly IEnvironmentVariables _environmentVariables = new MockEnvironmentVariables() { { "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL", "http://localhost:12345" } };
+ private readonly IConfiguration _configuration;
+
+ public DashboardClientTests()
+ {
+ var configuration = new ConfigurationManager();
+ configuration.AddInMemoryCollection(new Dictionary() { { "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL", "http://localhost:12345" } });
+ _configuration = configuration;
+ }
[Fact]
public async Task SubscribeResources_OnCancel_ChannelRemoved()
{
- var instance = new DashboardClient(NullLoggerFactory.Instance, _environmentVariables);
+ var instance = new DashboardClient(NullLoggerFactory.Instance, _configuration);
IDashboardClient client = instance;
var cts = new CancellationTokenSource();
@@ -42,7 +50,7 @@ public async Task SubscribeResources_OnCancel_ChannelRemoved()
[Fact]
public async Task SubscribeResources_OnDispose_ChannelRemoved()
{
- var instance = new DashboardClient(NullLoggerFactory.Instance, _environmentVariables);
+ var instance = new DashboardClient(NullLoggerFactory.Instance, _configuration);
IDashboardClient client = instance;
Assert.Equal(0, instance.OutgoingResourceSubscriberCount);
@@ -68,7 +76,7 @@ public async Task SubscribeResources_OnDispose_ChannelRemoved()
[Fact]
public async Task SubscribeResources_ThrowsIfDisposed()
{
- IDashboardClient client = new DashboardClient(NullLoggerFactory.Instance, _environmentVariables);
+ IDashboardClient client = new DashboardClient(NullLoggerFactory.Instance, _configuration);
await client.DisposeAsync();
@@ -78,7 +86,7 @@ public async Task SubscribeResources_ThrowsIfDisposed()
[Fact]
public async Task SubscribeResources_IncreasesSubscriberCount()
{
- var instance = new DashboardClient(NullLoggerFactory.Instance, _environmentVariables);
+ var instance = new DashboardClient(NullLoggerFactory.Instance, _configuration);
IDashboardClient client = instance;
Assert.Equal(0, instance.OutgoingResourceSubscriberCount);