Skip to content

Commit 06d5985

Browse files
Copilotaaronpowell
andauthored
Remove deprecated IDistributedApplicationLifecycleHook interface (#915)
* Initial plan * Replace IDistributedApplicationLifecycleHook with event-based patterns Co-authored-by: aaronpowell <[email protected]> * Add tests for installer resources and update Dapr tests Co-authored-by: aaronpowell <[email protected]> * Refactor Dapr to use IDistributedApplicationEventingSubscriber Co-authored-by: aaronpowell <[email protected]> * Fixing build issue * Updating the endpoint port * Disabling some tests so we can move forward in other parts of the Aspire 13 update --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: aaronpowell <[email protected]> Co-authored-by: Aaron Powell <[email protected]>
1 parent 2ebfea3 commit 06d5985

File tree

18 files changed

+221
-510
lines changed

18 files changed

+221
-510
lines changed

examples/deno/CommunityToolkit.Aspire.Hosting.Deno.AppHost/Program.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using CommunityToolkit.Aspire.Hosting.Deno;
2-
31
var builder = DistributedApplication.CreateBuilder(args);
42

53
builder.AddDenoTask("vite-demo", taskName: "dev")

src/CommunityToolkit.Aspire.Hosting.Bun/BunAppExtensions.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using Aspire.Hosting.ApplicationModel;
2-
using Aspire.Hosting.Lifecycle;
3-
using CommunityToolkit.Aspire.Hosting.Bun;
42
using CommunityToolkit.Aspire.Utils;
53
using Microsoft.Extensions.Hosting;
64

@@ -46,10 +44,27 @@ public static IResourceBuilder<BunAppResource> AddBunApp(
4644
/// Ensures the Bun packages are installed before the application starts using Bun as the package manager.
4745
/// </summary>
4846
/// <param name="resource">The Bun app resource.</param>
47+
/// <param name="configureInstaller">Configure the Bun installer resource.</param>
4948
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
50-
public static IResourceBuilder<BunAppResource> WithBunPackageInstallation(this IResourceBuilder<BunAppResource> resource)
49+
public static IResourceBuilder<BunAppResource> WithBunPackageInstallation(this IResourceBuilder<BunAppResource> resource, Action<IResourceBuilder<BunInstallerResource>>? configureInstaller = null)
5150
{
52-
resource.ApplicationBuilder.Services.TryAddLifecycleHook<BunPackageInstallerLifecycleHook>();
51+
// Only install packages during development, not in publish mode
52+
if (!resource.ApplicationBuilder.ExecutionContext.IsPublishMode)
53+
{
54+
var installerName = $"{resource.Resource.Name}-bun-install";
55+
var installer = new BunInstallerResource(installerName, resource.Resource.WorkingDirectory);
56+
57+
var installerBuilder = resource.ApplicationBuilder.AddResource(installer)
58+
.WithArgs("install")
59+
.WithParentRelationship(resource.Resource)
60+
.ExcludeFromManifest();
61+
62+
// Make the parent resource wait for the installer to complete
63+
resource.WaitForCompletion(installerBuilder);
64+
65+
configureInstaller?.Invoke(installerBuilder);
66+
}
67+
5368
return resource;
5469
}
5570

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Aspire.Hosting.ApplicationModel;
2+
3+
/// <summary>
4+
/// A resource that represents a Bun package installer.
5+
/// </summary>
6+
/// <param name="name">The name of the resource.</param>
7+
/// <param name="workingDirectory">The working directory to use for the command.</param>
8+
public class BunInstallerResource(string name, string workingDirectory)
9+
: ExecutableResource(name, "bun", workingDirectory);

src/CommunityToolkit.Aspire.Hosting.Bun/BunPackageInstallerLifecycleHook.cs

Lines changed: 0 additions & 126 deletions
This file was deleted.

src/CommunityToolkit.Aspire.Hosting.Dapr/DaprDistributedApplicationLifecycleHook.cs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@
77
using Aspire.Hosting.Lifecycle;
88
using Aspire.Hosting.Utils;
99
using Microsoft.Extensions.Configuration;
10-
using Microsoft.Extensions.DependencyInjection;
1110
using Microsoft.Extensions.Hosting;
1211
using Microsoft.Extensions.Logging;
1312
using Microsoft.Extensions.Options;
1413
using System.Diagnostics.CodeAnalysis;
1514
using System.Globalization;
1615
using System.Net.Sockets;
17-
using System.Threading.Tasks;
1816
using static CommunityToolkit.Aspire.Hosting.Dapr.CommandLineArgs;
1917

2018
namespace CommunityToolkit.Aspire.Hosting.Dapr;
@@ -23,14 +21,21 @@ internal sealed class DaprDistributedApplicationLifecycleHook(
2321
IConfiguration configuration,
2422
IHostEnvironment environment,
2523
ILogger<DaprDistributedApplicationLifecycleHook> logger,
26-
IOptions<DaprOptions> options) : IDistributedApplicationLifecycleHook, IDisposable
24+
IOptions<DaprOptions> options) : IDistributedApplicationEventingSubscriber, IDisposable
2725
{
2826
private readonly DaprOptions _options = options.Value;
2927

3028
private string? _onDemandResourcesRootPath;
3129

32-
public async Task BeforeStartAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
30+
public Task SubscribeAsync(IDistributedApplicationEventing eventing, DistributedApplicationExecutionContext executionContext, CancellationToken cancellationToken)
3331
{
32+
eventing.Subscribe<BeforeStartEvent>(OnBeforeStartAsync);
33+
return Task.CompletedTask;
34+
}
35+
36+
private async Task OnBeforeStartAsync(BeforeStartEvent @event, CancellationToken cancellationToken = default)
37+
{
38+
var appModel = @event.Model;
3439
string appHostDirectory = GetAppHostDirectory();
3540

3641
// Set up WaitAnnotations for Dapr components based on their value provider dependencies
@@ -91,7 +96,7 @@ public async Task BeforeStartAsync(DistributedApplicationModel appModel, Cancell
9196
hasValueProviders = true;
9297
}
9398
}
94-
99+
95100
// Check if there are any secrets that need to be added to the secret store
96101
if (componentReferenceAnnotation.Component.TryGetAnnotationsOfType<DaprComponentSecretAnnotation>(out var secretAnnotations))
97102
{
@@ -100,7 +105,7 @@ public async Task BeforeStartAsync(DistributedApplicationModel appModel, Cancell
100105
secrets[secretAnnotation.Key] = (await secretAnnotation.Value.GetValueAsync(cancellationToken))!;
101106
}
102107
}
103-
108+
104109
// If we have any secrets or value providers, ensure the secret store path is added
105110
if ((secrets.Count > 0 || hasValueProviders) && onDemandResourcesPaths.TryGetValue("secretstore", out var secretStorePath))
106111
{
@@ -139,7 +144,7 @@ public async Task BeforeStartAsync(DistributedApplicationModel appModel, Cancell
139144
{
140145
context.EnvironmentVariables.TryAdd(secret.Key, secret.Value);
141146
}
142-
147+
143148
// Add value provider references
144149
foreach (var (envVarName, valueProvider) in endpointEnvironmentVars)
145150
{
@@ -509,10 +514,10 @@ private async Task<IReadOnlyDictionary<string, string>> StartOnDemandDaprCompone
509514
.ToList();
510515

511516
// If any of the components have secrets or value provider references, we will add an on-demand secret store component.
512-
bool needsSecretStore = onDemandComponents.Any(component =>
517+
bool needsSecretStore = onDemandComponents.Any(component =>
513518
(component.TryGetAnnotationsOfType<DaprComponentSecretAnnotation>(out var secretAnnotations) && secretAnnotations.Any()) ||
514519
(component.TryGetAnnotationsOfType<DaprComponentValueProviderAnnotation>(out var valueProviderAnnotations) && valueProviderAnnotations.Any()));
515-
520+
516521
if (needsSecretStore)
517522
{
518523
onDemandComponents.Add(new DaprComponentResource("secretstore", DaprConstants.BuildingBlocks.SecretStore));

src/CommunityToolkit.Aspire.Hosting.Dapr/IDistributedApplicationBuilderExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static IDistributedApplicationBuilder AddDapr(this IDistributedApplicatio
3030
builder.Services.Configure(configure);
3131
}
3232

33-
builder.Services.TryAddLifecycleHook<DaprDistributedApplicationLifecycleHook>();
33+
builder.Services.TryAddEventingSubscriber<DaprDistributedApplicationLifecycleHook>();
3434

3535
return builder;
3636
}

src/CommunityToolkit.Aspire.Hosting.Deno/DenoAppHostingExtensions.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using Aspire.Hosting.ApplicationModel;
2-
using Aspire.Hosting.Lifecycle;
32
using Microsoft.Extensions.Hosting;
43
using CommunityToolkit.Aspire.Utils;
5-
using CommunityToolkit.Aspire.Hosting.Deno;
64

75
namespace Aspire.Hosting;
86
/// <summary>
@@ -73,10 +71,27 @@ public static IResourceBuilder<DenoAppResource> AddDenoTask(this IDistributedApp
7371
/// Ensures the Deno packages are installed before the application starts using Deno as the package manager.
7472
/// </summary>
7573
/// <param name="resource">The Deno app resource.</param>
74+
/// <param name="configureInstaller">Configure the Deno installer resource.</param>
7675
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
77-
public static IResourceBuilder<DenoAppResource> WithDenoPackageInstallation(this IResourceBuilder<DenoAppResource> resource)
76+
public static IResourceBuilder<DenoAppResource> WithDenoPackageInstallation(this IResourceBuilder<DenoAppResource> resource, Action<IResourceBuilder<DenoInstallerResource>>? configureInstaller = null)
7877
{
79-
resource.ApplicationBuilder.Services.TryAddLifecycleHook<DenoPackageInstallerLifecycleHook>();
78+
// Only install packages during development, not in publish mode
79+
if (!resource.ApplicationBuilder.ExecutionContext.IsPublishMode)
80+
{
81+
var installerName = $"{resource.Resource.Name}-deno-install";
82+
var installer = new DenoInstallerResource(installerName, resource.Resource.WorkingDirectory);
83+
84+
var installerBuilder = resource.ApplicationBuilder.AddResource(installer)
85+
.WithArgs("install")
86+
.WithParentRelationship(resource.Resource)
87+
.ExcludeFromManifest();
88+
89+
// Make the parent resource wait for the installer to complete
90+
resource.WaitForCompletion(installerBuilder);
91+
92+
configureInstaller?.Invoke(installerBuilder);
93+
}
94+
8095
return resource;
8196
}
8297

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Aspire.Hosting.ApplicationModel;
2+
3+
/// <summary>
4+
/// A resource that represents a Deno package installer.
5+
/// </summary>
6+
/// <param name="name">The name of the resource.</param>
7+
/// <param name="workingDirectory">The working directory to use for the command.</param>
8+
public class DenoInstallerResource(string name, string workingDirectory)
9+
: ExecutableResource(name, "deno", workingDirectory);

0 commit comments

Comments
 (0)