Console and worker apps

यह कंटेंट अभी तक आपकी भाषा में उपलब्ध नहीं है।

Console applications and background workers can participate in an Aspire application regardless of the language they’re written in. Add them to your AppHost to manage their lifecycle alongside your other resources, provide connection strings and service endpoints, and view their console output in the dashboard.

Choose the resource type that matches how your app runs. Use an executable resource for a command-line program, a Python app resource for a script or module, or a JavaScript app resource for a Node.js app. For a .NET console app or Worker Service project, use a project resource. None of these apps needs to expose an HTTP endpoint to be orchestrated by Aspire.

For more information on executable, Python, and JavaScript resources, see Executable resources, Python integration, and JavaScript integration.

The following examples show how to add a .NET or Node.js console app, connect it to other resources, and run it as a background worker. The examples use three sets of tabs, which you choose independently:

  • Aspire CLI, apphost.cs (C# file-based app), and PackageReference(*.csproj) tabs select an installation method for Aspire integrations. If you’re using a TypeScript AppHost, only the Aspire CLI tab is applicable.
  • .NET and Node.js tabs select the language of the console app or executable that the AppHost orchestrates.
  • C# and TypeScript tabs select the language of the AppHost itself.

For example, to orchestrate a Node.js console app from a C# AppHost, choose any installation method, then Node.js, and then C#. Your selections stay the same as you move through the page.

These examples assume an existing AppHost.

  • .NET: The examples also assume a shared service defaults project. Create the named console, worker, and API projects before referencing them. In a C# AppHost, add project references so the corresponding Projects.* types are generated; in a TypeScript AppHost, use each project’s actual path.
  • Node.js: Create each app folder with a package.json file before referencing it. The AppHost resolves the app folder path relative to the AppHost directory, and the script path relative to the app folder.

For the Redis examples, install the hosting integration in your AppHost. Running Redis also requires a supported container runtime.

Aspire CLI — Aspire.Hosting.Redis पैकेज जोड़ें
aspire add redis

Aspire CLI इंटरैक्टिव है; प्रॉम्प्ट पर उपयुक्त परिणाम चुनें:

Aspire CLI — उदाहरण आउटपुट
Select an integration to add:
> redis (Aspire.Hosting.Redis)
> Other results listed as selectable options...

Add the console app project to your AppHost:

apphost.mts
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const cache = await builder.addRedis('cache');
// Add a console app project to the AppHost
await builder
.addProject('processor', '../MyConsoleApp/MyConsoleApp.csproj')
.withReference(cache);
await builder.build().run();

The processor project receives the ConnectionStrings__cache environment variable at runtime, just like any other project type.

Console apps can call HTTP services that the AppHost manages. The following walkthrough assumes a CatalogService API project that exposes an HTTP endpoint at /, and a console app named processor that calls it.

Console apps using the .NET Generic Host can use the same service discovery infrastructure as web apps. This walkthrough uses a MyConsoleApp console project.

  1. From the console project directory, install the hosting package:

    .NET CLI — Add Microsoft.Extensions.Hosting package
    dotnet add package Microsoft.Extensions.Hosting

    Add a reference to your existing service defaults project in the console project’s MyConsoleApp.csproj. Replace the example path with your project’s actual path:

    MyConsoleApp.csproj
    <ItemGroup>
    <ProjectReference Include="..\MyApp.ServiceDefaults\MyApp.ServiceDefaults.csproj" />
    </ItemGroup>
  2. Add a typed HTTP client to the console project:

    CatalogClient.cs
    using System.Net.Http;
    public sealed class CatalogClient(HttpClient httpClient)
    {
    public Task<string> GetAsync(CancellationToken cancellationToken = default)
    => httpClient.GetStringAsync("/", cancellationToken);
    }
  3. Configure the host in your console app’s Program.cs. This example starts the host, calls the catalog API, and then stops:

    Program.cs
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    var builder = Host.CreateApplicationBuilder(args);
    // Add service defaults (telemetry, health checks, service discovery)
    builder.AddServiceDefaults();
    // Register your services
    builder.Services.AddHttpClient<CatalogClient>(
    client => client.BaseAddress = new Uri("https+http://catalog"));
    using var app = builder.Build();
    await app.StartAsync();
    var catalogClient = app.Services.GetRequiredService<CatalogClient>();
    Console.WriteLine(await catalogClient.GetAsync());
    await app.StopAsync();
  4. In the AppHost, reference the services this app depends on:

    apphost.mts
    import { createBuilder } from './.aspire/modules/aspire.mjs';
    const builder = await createBuilder();
    const catalog = await builder.addProject(
    'catalog',
    '../CatalogService/CatalogService.csproj'
    );
    const processor = await builder.addProject(
    'processor',
    '../MyConsoleApp/MyConsoleApp.csproj'
    );
    await processor.withReference(catalog);
    await processor.waitFor(catalog);
    await builder.build().run();

The WithReference(catalog) call injects service discovery configuration so processor can resolve https+http://catalog to the running catalog service endpoint.

Background workers run for as long as the AppHost runs and stop when it shuts down. In .NET, Worker Service projects are the recommended pattern for long-running background tasks with Aspire. In Node.js, use a script that loops until it receives a shutdown signal.

Worker Service projects use IHostedService (or BackgroundService) and integrate naturally with the .NET Generic Host.

Create a DataWorker project with the Worker Service template, then add a reference to your shared service defaults project as shown in the console walkthrough:

.NET CLI
dotnet new worker --name DataWorker --output DataWorker

From the DataWorker directory, install the Redis client integration. This package supplies AddRedisClient; the AppHost’s hosting package doesn’t register a client in the worker:

.NET CLI — Add Aspire.StackExchange.Redis package
dotnet add package Aspire.StackExchange.Redis

Replace the generated worker class with DataProcessor.cs. Its DoWorkAsync method is a placeholder for your application’s processing logic; registering the Redis client doesn’t itself perform Redis operations.

DataProcessor.cs
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
public class DataProcessor : BackgroundService
{
private readonly ILogger<DataProcessor> _logger;
public DataProcessor(ILogger<DataProcessor> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Processing data at: {Time}", DateTimeOffset.UtcNow);
await DoWorkAsync(stoppingToken);
await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
}
}
private Task DoWorkAsync(CancellationToken stoppingToken)
{
// Replace with your background work.
return Task.CompletedTask;
}
}
Program.cs
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
builder.AddServiceDefaults();
// Register resource connections
builder.AddRedisClient("cache");
// Register the background worker
builder.Services.AddHostedService<DataProcessor>();
var app = builder.Build();
await app.RunAsync();

The following model also provides a PostgreSQL database. Install its hosting integration in the AppHost before using this example:

Aspire CLI — Aspire.Hosting.PostgreSQL पैकेज जोड़ें
aspire add postgresql

Aspire CLI इंटरैक्टिव है; प्रॉम्प्ट पर उपयुक्त परिणाम चुनें:

Aspire CLI — उदाहरण आउटपुट
Select an integration to add:
> postgresql (Aspire.Hosting.PostgreSQL)
> Other results listed as selectable options...

The database reference supplies connection information, but the worker above doesn’t yet use it. To add database operations, configure a client as described in Connect to PostgreSQL.

Add the Worker Service project to your AppHost:

apphost.mts
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const cache = await builder.addRedis('cache');
const postgres = await builder.addPostgres('postgres');
const db = await postgres.addDatabase('app-db');
const worker = await builder.addProject(
'data-worker',
'../DataWorker/DataWorker.csproj'
);
await worker.withReference(cache);
await worker.withReference(db);
await worker.waitFor(db);
await builder.build().run();

For more information on the Redis and PostgreSQL hosting integrations, see Redis integration and PostgreSQL integration.

By default, all resources start automatically when the AppHost runs. For console apps that should only run on demand, use WithExplicitStart.

In your AppHost, add the console app project with WithExplicitStart:

apphost.mts
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const tool = await builder.addProject(
'tool',
'../MyInteractiveTool/MyInteractiveTool.csproj'
);
await tool.withExplicitStart();
await builder.build().run();

With WithExplicitStart, the resource appears in the Aspire dashboard but doesn’t start automatically. You can start it manually from the dashboard or programmatically.

Aspire builds that include the experimental WithTerminal API support interactive terminal user interfaces (TUIs) and shell-based experiences that need a live, bidirectional session, separately from the dashboard’s console log viewer.

Aspire captures stdout and stderr from all managed resources and displays them in the dashboard’s Console logs page. Console apps output is fully visible, including colored text (ANSI escape codes are rendered).

For more information, see Console logs page.

For structured logging in console apps, use ILogger instead of Console.Write. The following fragment assumes an existing logger and item identifier:

Program.cs
// Prefer structured logging
logger.LogInformation("Processing item {ItemId}", itemId);
// Instead of
Console.WriteLine($"Processing item {itemId}");

With console logging and OpenTelemetry logging/export configured, such as through the service defaults setup above, logs appear in both the Console logs and Structured logs views of the dashboard. Calling ILogger alone doesn’t export structured logs to the dashboard.

Using connection strings without service defaults

Section titled “Using connection strings without service defaults”

Apps that don’t use the service defaults project, such as a minimal .NET console app without a host or any Node.js app, can read connection information directly from environment variables.

For the configuration API example, install the environment variables configuration provider in your console project:

.NET CLI — Add Microsoft.Extensions.Configuration.EnvironmentVariables package
dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables
Program.cs
// For .NET apps, read from configuration
using Microsoft.Extensions.Configuration;
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
var redisConnection = config.GetConnectionString("cache");
// Or equivalently:
var redisConnection2 = Environment.GetEnvironmentVariable("ConnectionStrings__cache");