Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Clean up
  • Loading branch information
JamesNK committed Jul 14, 2025
commit 80f9b56d73613e64f45e08f0617e640bb4ea5507
2 changes: 1 addition & 1 deletion src/Aspire.Hosting/DistributedApplicationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options)
_innerBuilder.Services.AddHostedService<DistributedApplicationLifecycle>();
_innerBuilder.Services.AddHostedService<DistributedApplicationRunner>();
_innerBuilder.Services.AddHostedService<VersionCheckService>();
_innerBuilder.Services.AddSingleton<IVersionFetcher, VersionFetcher>();
_innerBuilder.Services.AddSingleton<IPackageFetcher, PackageFetcher>();
_innerBuilder.Services.AddSingleton(options);
_innerBuilder.Services.AddSingleton<ResourceNotificationService>();
_innerBuilder.Services.AddSingleton<ResourceLoggerService>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Aspire.Hosting.VersionChecking;

internal interface IVersionFetcher
internal interface IPackageFetcher
{
Task<List<NuGetPackage>> TryFetchVersionsAsync(string appHostDirectory, CancellationToken cancellationToken);
Task<List<NuGetPackage>> TryFetchPackagesAsync(string appHostDirectory, CancellationToken cancellationToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@

namespace Aspire.Hosting.VersionChecking;

internal sealed class VersionFetcher : IVersionFetcher
internal sealed class PackageFetcher : IPackageFetcher
{
public const string PackageId = "Aspire.Hosting.AppHost";

private readonly ILogger<VersionFetcher> _logger;
private readonly ILogger<PackageFetcher> _logger;

public VersionFetcher(ILogger<VersionFetcher> logger)
public PackageFetcher(ILogger<PackageFetcher> logger)
{
_logger = logger;
}

public async Task<List<NuGetPackage>> TryFetchVersionsAsync(string appHostDirectory, CancellationToken cancellationToken)
public async Task<List<NuGetPackage>> TryFetchPackagesAsync(string appHostDirectory, CancellationToken cancellationToken)
{
var outputJson = new StringBuilder();
var spec = new ProcessSpec("dotnet")
Expand Down
8 changes: 4 additions & 4 deletions src/Aspire.Hosting/VersionChecking/VersionCheckService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,20 @@ internal sealed class VersionCheckService : BackgroundService
private readonly ILogger<VersionCheckService> _logger;
private readonly IConfiguration _configuration;
private readonly DistributedApplicationOptions _options;
private readonly IVersionFetcher _versionFetcher;
private readonly IPackageFetcher _packageFetcher;
private readonly DistributedApplicationExecutionContext _executionContext;
private readonly TimeProvider _timeProvider;
private readonly SemVersion? _appHostVersion;

public VersionCheckService(IInteractionService interactionService, ILogger<VersionCheckService> logger,
IConfiguration configuration, DistributedApplicationOptions options, IVersionFetcher versionFetcher,
IConfiguration configuration, DistributedApplicationOptions options, IPackageFetcher packageFetcher,
DistributedApplicationExecutionContext executionContext, TimeProvider timeProvider)
{
_interactionService = interactionService;
_logger = logger;
_configuration = configuration;
_options = options;
_versionFetcher = versionFetcher;
_packageFetcher = packageFetcher;
_executionContext = executionContext;
_timeProvider = timeProvider;

Expand Down Expand Up @@ -98,7 +98,7 @@ private async Task CheckForLatestAsync(CancellationToken cancellationToken)
var appHostDirectory = _configuration["AppHost:Directory"]!;

SecretsStore.TrySetUserSecret(_options.Assembly, LastCheckDateKey, now.ToString("o", CultureInfo.InvariantCulture));
var packages = await _versionFetcher.TryFetchVersionsAsync(appHostDirectory, cancellationToken).ConfigureAwait(false);
var packages = await _packageFetcher.TryFetchPackagesAsync(appHostDirectory, cancellationToken).ConfigureAwait(false);

latestVersion = PackageUpdateHelpers.GetNewerVersion(_appHostVersion, packages);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ public async Task ExecuteAsync_NewerVersion_DisplayMessage()
var interactionService = new TestInteractionService();
var configurationManager = new ConfigurationManager();
var versionTcs = new TaskCompletionSource<List<NuGetPackage>>();
var versionFetcher = new TestVersionFetcher(versionTcs.Task);
var versionFetcher = new TestPackageFetcher(versionTcs.Task);
var options = new DistributedApplicationOptions();
var service = CreateVersionCheckService(interactionService: interactionService, versionFetcher: versionFetcher, configuration: configurationManager, options: options);
var service = CreateVersionCheckService(interactionService: interactionService, packageFetcher: versionFetcher, configuration: configurationManager, options: options);

// Act
_ = service.StartAsync(CancellationToken.None);

versionTcs.TrySetResult([new NuGetPackage { Id = VersionFetcher.PackageId, Version = "100.0.0" }]);
versionTcs.TrySetResult([new NuGetPackage { Id = PackageFetcher.PackageId, Version = "100.0.0" }]);

var interaction = await interactionService.Interactions.Reader.ReadAsync().DefaultTimeout();
interaction.CompletionTcs.TrySetResult(InteractionResult.Ok(true));
Expand All @@ -50,9 +50,9 @@ public async Task ExecuteAsync_DisabledInConfiguration_NoFetch()
{
[KnownConfigNames.VersionCheckDisabled] = "true"
});
var versionFetcher = new TestVersionFetcher();
var versionFetcher = new TestPackageFetcher();
var options = new DistributedApplicationOptions();
var service = CreateVersionCheckService(interactionService: interactionService, versionFetcher: versionFetcher, configuration: configurationManager, options: options);
var service = CreateVersionCheckService(interactionService: interactionService, packageFetcher: versionFetcher, configuration: configurationManager, options: options);

// Act
_ = service.StartAsync(CancellationToken.None);
Expand All @@ -79,10 +79,10 @@ public async Task ExecuteAsync_InsideLastCheckInterval_NoFetch()
});

var versionTcs = new TaskCompletionSource<List<NuGetPackage>>();
var versionFetcher = new TestVersionFetcher(versionTcs.Task);
var versionFetcher = new TestPackageFetcher(versionTcs.Task);
var service = CreateVersionCheckService(
interactionService: interactionService,
versionFetcher: versionFetcher,
packageFetcher: versionFetcher,
configuration: configurationManager,
timeProvider: timeProvider);

Expand Down Expand Up @@ -115,10 +115,10 @@ public async Task ExecuteAsync_InsideLastCheckIntervalHasLastKnown_NoFetchAndDis
});

var versionTcs = new TaskCompletionSource<List<NuGetPackage>>();
var versionFetcher = new TestVersionFetcher(versionTcs.Task);
var versionFetcher = new TestPackageFetcher(versionTcs.Task);
var service = CreateVersionCheckService(
interactionService: interactionService,
versionFetcher: versionFetcher,
packageFetcher: versionFetcher,
configuration: configurationManager,
timeProvider: timeProvider);

Expand All @@ -141,13 +141,13 @@ public async Task ExecuteAsync_OlderVersion_NoMessage()
var interactionService = new TestInteractionService();
var configurationManager = new ConfigurationManager();
var versionTcs = new TaskCompletionSource<List<NuGetPackage>>();
var versionFetcher = new TestVersionFetcher(versionTcs.Task);
var service = CreateVersionCheckService(interactionService: interactionService, versionFetcher: versionFetcher, configuration: configurationManager);
var versionFetcher = new TestPackageFetcher(versionTcs.Task);
var service = CreateVersionCheckService(interactionService: interactionService, packageFetcher: versionFetcher, configuration: configurationManager);

// Act
_ = service.StartAsync(CancellationToken.None);

versionTcs.SetResult([new NuGetPackage { Id = VersionFetcher.PackageId, Version = "0.1.0" }]);
versionTcs.SetResult([new NuGetPackage { Id = PackageFetcher.PackageId, Version = "0.1.0" }]);

await service.ExecuteTask!.DefaultTimeout();

Expand All @@ -170,13 +170,13 @@ public async Task ExecuteAsync_IgnoredVersion_NoMessage()
[VersionCheckService.IgnoreVersionKey] = "100.0.0"
});
var versionTcs = new TaskCompletionSource<List<NuGetPackage>>();
var versionFetcher = new TestVersionFetcher(versionTcs.Task);
var service = CreateVersionCheckService(interactionService: interactionService, versionFetcher: versionFetcher, configuration: configurationManager);
var versionFetcher = new TestPackageFetcher(versionTcs.Task);
var service = CreateVersionCheckService(interactionService: interactionService, packageFetcher: versionFetcher, configuration: configurationManager);

// Act
_ = service.StartAsync(CancellationToken.None);

versionTcs.SetResult([new NuGetPackage { Id = VersionFetcher.PackageId, Version = "100.0.0" }]);
versionTcs.SetResult([new NuGetPackage { Id = PackageFetcher.PackageId, Version = "100.0.0" }]);

await service.ExecuteTask!.DefaultTimeout();

Expand All @@ -190,7 +190,7 @@ public async Task ExecuteAsync_IgnoredVersion_NoMessage()

private static VersionCheckService CreateVersionCheckService(
IInteractionService? interactionService = null,
IVersionFetcher? versionFetcher = null,
IPackageFetcher? packageFetcher = null,
IConfiguration? configuration = null,
TimeProvider? timeProvider = null,
DistributedApplicationOptions? options = null)
Expand All @@ -200,7 +200,7 @@ private static VersionCheckService CreateVersionCheckService(
NullLogger<VersionCheckService>.Instance,
configuration ?? new ConfigurationManager(),
options ?? new DistributedApplicationOptions(),
versionFetcher ?? new TestVersionFetcher(),
packageFetcher ?? new TestPackageFetcher(),
new DistributedApplicationExecutionContext(new DistributedApplicationOperation()),
timeProvider ?? new TestTimeProvider());
}
Expand All @@ -217,18 +217,18 @@ public override DateTimeOffset GetUtcNow()
}
}

private sealed class TestVersionFetcher : IVersionFetcher
private sealed class TestPackageFetcher : IPackageFetcher
{
private readonly Task<List<NuGetPackage>> _versionTask;

public bool FetchCalled { get; private set; }

public TestVersionFetcher(Task<List<NuGetPackage>>? versionTask = null)
public TestPackageFetcher(Task<List<NuGetPackage>>? versionTask = null)
{
_versionTask = versionTask ?? Task.FromResult<List<NuGetPackage>>([]);
}

public Task<List<NuGetPackage>> TryFetchVersionsAsync(string appHostDirectory, CancellationToken cancellationToken)
public Task<List<NuGetPackage>> TryFetchPackagesAsync(string appHostDirectory, CancellationToken cancellationToken)
{
FetchCalled = true;
return _versionTask;
Expand Down