Set up .NET / C# apps in the AppHost

Цей контент ще не доступний вашою мовою.

C# logo

This article is the reference for the Aspire Dotnet hosting integration. It enumerates the AppHost APIs — with examples for both AppHost.cs and apphost.mts — that you use to add C# projects and file-based C# apps by path in your AppHost project.

If you’re new to the Dotnet integration, start with the Get started with the .NET / C# app integration guide.

If your C# AppHost needs to reference the resource type directly — for example, to declare a strongly typed variable or a method parameter — import it from the Aspire.Hosting.Dotnet namespace, matching the pattern used by the Go, Python, and JavaScript hosting integrations:

using Aspire.Hosting.Dotnet;
var builder = DistributedApplication.CreateBuilder(args);
IResourceBuilder<DotnetProjectResource> api =
builder.AddDotnetProject("api", "../api/api.csproj");

To start building an Aspire app that adds a C# project or file-based app by path, install the 📦 Aspire.Hosting.Dotnet NuGet package:

Terminal
aspire add Aspire.Hosting.Dotnet

Learn more about aspire add in the command reference.

This updates your aspire.config.json with the Dotnet hosting integration package:

aspire.config.json
{
"packages": {
"Aspire.Hosting.Dotnet": "13.6.0"
}
}

Add a C# project or file-based app by path

Section titled “Add a C# project or file-based app by path”

Use AddDotnetProject / addDotnetProject to add a C# project or file-based app resource by path. The path argument can point at a project file (.csproj), a directory containing a single .csproj, or a file-based app (.cs). If the path isn’t absolute, it’s computed relative to the AppHost directory.

apphost.mts
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const api = await builder.addDotnetProject('api', '../api/api.csproj');
await api.withHttpEndpoint({ port: 8080 });
await api.withExternalHttpEndpoints();
await builder.build().run();

The resource launches with dotnet run --project <path> for a project file, or dotnet run --file <path> for a file-based app. Endpoints, environment variables, and service discovery are configured from the project’s launchSettings.json and Kestrel configuration, matching AddProject<T>.

A file-based app is a single .cs file run directly with dotnet run --file, without a .csproj. File-based apps require .NET 10 or later.

apphost.mts
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
await builder.addDotnetProject('inventoryservice', '../InventoryService.cs');
await builder.build().run();

Pass a configuration action to set additional options such as the launch profile:

apphost.mts
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
await builder.addDotnetProject('inventoryservice', '../InventoryService.cs', {
launchProfileName: 'https',
});
await builder.build().run();

The resource is added as an ExecutableResource rather than a ProjectResource, so it doesn’t need to be referenced from the AppHost’s own solution. Before the resource starts, Aspire validates that the path resolves to a .csproj or .cs file (or a directory containing a single .csproj) and, for file-based apps, that the active .NET SDK version is 10 or later.

The TypeScript addDotnetProject overload accepts a plain options object rather than the shared ProjectResourceOptions handle used by the legacy addProject / addCSharpApp polyglot APIs, so it can be constructed directly from a generated SDK caller without an RPC round-trip:

apphost.mts
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
await builder.addDotnetProject('inventoryservice', '../InventoryService.cs', {
launchProfileName: 'https',
excludeLaunchProfile: false,
excludeKestrelEndpoints: false,
});
await builder.build().run();
  • Omitting the options object, or leaving launchProfileName unset or null, selects the default launch profile.
  • excludeLaunchProfile: true disables launch profiles entirely and takes precedence over a supplied launchProfileName.
  • excludeKestrelEndpoints: true stops Aspire from deriving model endpoints from the project’s Kestrel configuration. It doesn’t rewrite or disable the service’s own Kestrel configuration.

These properties have the same behavior as the corresponding LaunchProfileName, ExcludeLaunchProfile, and ExcludeKestrelEndpoints properties on the C# ProjectResourceOptions type. The options are polyglot-specific to addDotnetProject; they don’t change the shared ProjectResourceOptions handle used by the legacy addProject / addCSharpApp exports.

Automatic project publishing for DotnetProjectResource isn’t currently supported. A plain DotnetProjectResource causes aspire publish and aspire deploy to fail with an actionable error instead of emitting an executable.v0 manifest containing machine-local paths.

Use one of these alternatives:

  • Use AddProject<TProject>(...) for a project referenced by a C# AppHost.
  • Use AddCSharpApp(...) / addCSharpApp(...) for a path-based project or file-based app that should use standard .NET project publishing.
  • Call PublishAsDockerFile(...) / publishAsDockerFile(...) to configure container publishing explicitly.
  • Call ExcludeFromManifest() / excludeFromManifest() when the resource is intentionally available only during local orchestration.