Add sample Temporal integration for Aspire#127
Conversation
|
|
| var connectOptions = ClientEnvConfig.LoadClientConnectOptions(); | ||
| Console.WriteLine("\nAttempting to connect client to temporal server..."); | ||
|
|
||
| var client = await TemporalClient.ConnectAsync(connectOptions); |
There was a problem hiding this comment.
Aren't you supposed to be able to use Aspire to get client connectivity information too? Even if it is powered by env vars under the hood, one might expect a type-safe Aspire way to get a client or client options for the given "temporal" reference from other project.
There was a problem hiding this comment.
Aspire only does that through environment variables. There isn't anything type-safe configuration support specifically from aspire. Typically library authors would create their own using Microsoft.Extensions.Configuration bindings
There was a problem hiding this comment.
I mean from a caller POV. For instance, stuff like https://aspire.dev/integrations/databases/postgres/postgres-get-started/?lang=csharp#use-the-integration-in-client-projects. I would expect that you can just put a client on the DI container w/ a single Aspire helper. Sure you can always still manually create clients.
There was a problem hiding this comment.
I mean we could create an extension method that makes that a little nicer, but that would be a client specific library/package. From an aspire API perspective, they just inject configuration properties that get consumed .
There was a problem hiding this comment.
They inject configuration properties for those not wanting to use the helper, but they also provide a helper. I figure the nice aspect of "Aspire helper to make server, Aspire helper to make client" is valuable even though they can use the env vars directly of course, same as Postgres there.
Co-authored-by: Chad Retz <chad@temporal.io>
There was a problem hiding this comment.
Pull request overview
This PR adds a new Aspire integration sample set for Temporal and introduces a Temporal.Extensions.Aspire.Hosting library that defines Temporal resources (local dev server, Docker container, and Temporal CLI) with health checks and environment variable wiring for dependent projects.
Changes:
- Added an Aspire sample AppHost + client/worker + workflow projects under
src/AspireIntegrations. - Introduced
Temporal.Extensions.Aspire.Hostingwith custom Temporal resources, options, lifecycle subscriber, and health check extensions. - Added documentation and Aspire settings for running the new sample.
Reviewed changes
Copilot reviewed 28 out of 28 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| TemporalioSamples.sln | Adds the new Aspire integration projects into the solution under a new folder. |
| src/AspireIntegrations/TemporalioSamples.SampleWorkflow/TemporalioSamples.SampleWorkflow.csproj | New workflow project for the Aspire sample. |
| src/AspireIntegrations/TemporalioSamples.SampleWorkflow/SimpleWorkflow.cs | Sample workflow definition. |
| src/AspireIntegrations/TemporalioSamples.SampleWorkflow/SimpleActivities.cs | Sample activity definition. |
| src/AspireIntegrations/TemporalioSamples.SampleWorker/TemporalioSamples.SampleWorker.csproj | New worker project for the Aspire sample. |
| src/AspireIntegrations/TemporalioSamples.SampleWorker/Program.cs | Configures and runs a hosted Temporal worker via env-configured connectivity. |
| src/AspireIntegrations/TemporalioSamples.SampleClient/TemporalioSamples.SampleClient.csproj | New client project for the Aspire sample. |
| src/AspireIntegrations/TemporalioSamples.SampleClient/Program.cs | Connects to Temporal and starts the sample workflow. |
| src/AspireIntegrations/TemporalioSamples.SampleAppHost/TemporalioSamples.SampleAppHost.csproj | New Aspire AppHost project referencing the Temporal Aspire hosting library and sample projects. |
| src/AspireIntegrations/TemporalioSamples.SampleAppHost/Properties/launchSettings.json | Launch profiles for the AppHost. |
| src/AspireIntegrations/TemporalioSamples.SampleAppHost/appsettings.json | Logging configuration for AppHost. |
| src/AspireIntegrations/TemporalioSamples.SampleAppHost/appsettings.Development.json | Development logging configuration for AppHost. |
| src/AspireIntegrations/TemporalioSamples.SampleAppHost/AppHost.cs | Wires up the Temporal local dev server resource and references it from worker/client. |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/TemporalResourceOptions.cs | Adds Temporal resource options layered on Temporal’s local environment options. |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/TemporalResourceConstants.cs | Defines endpoint names, default ports, and image constants. |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/TemporalLocalResourceSubscriber.cs | Manages local dev server lifecycle (start on init, shutdown on stop). |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/TemporalLocalResourceExtensions.cs | Adds AddTemporalLocalDevServer, endpoints, health checks, and dashboard commands. |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/TemporalLocalResource.cs | Resource model for the local dev server. |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/TemporalHealthCheckBuilderExtensions.cs | Adds health check registration helper for Temporal connectivity. |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/TemporalHealthCheck.cs | Implements the Temporal connectivity health check. |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/TemporalContainerResource.cs | Container-based Temporal resource + connection string expression. |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/TemporalContainerOptions.cs | Container-specific options (image tag) for Temporal. |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/TemporalContainerBuilderExtensions.cs | Adds Docker-based Temporal dev server resource and wiring helpers. |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/TemporalCliServerResourceExtensions.cs | Adds Temporal CLI-based server resource and wiring helpers. |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/TemporalCliServerResource.cs | Executable-based Temporal resource + connection string expression. |
| src/AspireIntegrations/Temporal.Extensions.Aspire.Hosting/Temporal.Extensions.Aspire.Hosting.csproj | New hosting library project definition and dependencies. |
| src/AspireIntegrations/README.md | Adds documentation for running/using the new Aspire integration and configuration options. |
| src/AspireIntegrations/.aspire/settings.json | Points Aspire tooling at the new AppHost project. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFramework>net10.0</TargetFramework> |
| public new List<string> AdditionalNamespaces | ||
| { | ||
| get => additionalNamespaces.Count > 0 ? additionalNamespaces : [Namespace]; | ||
| set => additionalNamespaces = value ?? []; |
| if (resource.WorkflowEnvironment != null) | ||
| { | ||
| resourceLogger.LogInformation("Shutting down Temporal test server '{ResourceName}'...", resource.Name); | ||
| await resource.WorkflowEnvironment.ShutdownAsync(); | ||
| resource.WorkflowEnvironment = null; | ||
| resourceLogger.LogInformation("Temporal test server '{ResourceName}' shut down successfully.", resource.Name); | ||
| } | ||
|
|
||
| // Publish ResourceStoppedEvent to trigger subscriber cleanup and keep _environments dictionary in sync | ||
| var resourceEvent = new ResourceEvent(resource, resource.Name, new CustomResourceSnapshot | ||
| { | ||
| ResourceType = "temporal-local", | ||
| CreationTimeStamp = DateTime.UtcNow, | ||
| State = KnownResourceStates.Exited, | ||
| Properties = [] | ||
| }); | ||
| var stoppedEvent = new ResourceStoppedEvent(resource, context.ServiceProvider, resourceEvent); | ||
| await eventing.PublishAsync(stoppedEvent, context.CancellationToken); | ||
|
|
| { | ||
| try | ||
| { | ||
| await TemporalClient.ConnectAsync(clientConnectOptions); |
|
|
||
| public ReferenceExpression ConnectionStringExpression => | ||
| ReferenceExpression.Create( | ||
| $"{PrimaryEndpoint.Property(EndpointProperty.Url)}"); |
| var builder = DistributedApplication.CreateBuilder(args); | ||
|
|
||
| // Add Temporal local server | ||
| var temporal = builder.AddTemporalLocalTestServer(); | ||
|
|
||
| // Add a worker project that depends on Temporal | ||
| builder.AddProject<Projects.SampleWorker>("worker") | ||
| .WaitFor(temporal) | ||
| .WithReference(temporal); | ||
|
|
||
| builder.Build().Run(); |
| options.DynamicConfigValues = [ | ||
| "persistence.cassandra.hosts = cassandra-host:9042" | ||
| ]; |
What was changed
This PR adds comprehensive .NET Aspire integration for Temporal, including:
Custom Aspire resource definitions for Temporal server deployment with three deployment models:
Temporalio.Testing.WorkflowEnvironmentTemporal.Extensions.Aspire.Hostinglibrary with:Sample Aspire application demonstrating the integration:
TemporalioSamples.SampleAppHost- Aspire app host configuring Temporal resourcesTemporalioSamples.SampleWorker- Worker service consuming workflows/activitiesTemporalioSamples.SampleClient- Client triggering workflow executionTemporalioSamples.SampleWorkflow- Simple workflow and activity definitions