Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
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
3 changes: 3 additions & 0 deletions docs/fundamentals/integrations-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ Client integrations wire up client libraries to [dependency injection (DI)](/dot

These packages configure existing client libraries to connect to hosting integrations. They extend the <xref:Microsoft.Extensions.Hosting.IHostApplicationBuilder> interface allowing client-consuming projects, such as your web app or API, to use the connected resource. The official [client integration NuGet packages](https://www.nuget.org/packages?q=owner%3A+aspire+tags%3A+aspire+client+integration&includeComputedFrameworks=true&prerel=true&sortby=relevance) are tagged with `aspire`, `integration`, and `client`. In addition to the official client integrations, the [community has created client integrations](../community-toolkit/overview.md) for various services and platforms as part of the Community Toolkit.

> [!IMPORTANT]
> .NET Aspire integrations require <xref:Microsoft.Extensions.Hosting.IHostApplicationBuilder> and are **not compatible** with `HostingStartup` implementations, which only provide access to <xref:Microsoft.AspNetCore.Hosting.IWebHostBuilder>. If you're using `HostingStartup` for modular configuration, see [HostingStartup is not supported with .NET Aspire integrations](../troubleshooting/hosting-startup-not-supported.md) for migration guidance.

For more information on creating a custom client integration, see [Create custom .NET Aspire client integrations](../extensibility/custom-client-integration.md).

### Relationship between hosting and client integrations
Expand Down
3 changes: 3 additions & 0 deletions docs/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,9 @@ items:
- name: Allow unsecure transport
displayName: unsecure transport,http,non-tls
href: troubleshooting/allow-unsecure-transport.md
- name: HostingStartup is not supported
displayName: hosting startup,IWebHostBuilder,IHostApplicationBuilder,migration
href: troubleshooting/hosting-startup-not-supported.md
- name: Untrusted localhost certificate
href: troubleshooting/untrusted-localhost-certificate.md
- name: Unable to install .NET Aspire workload
Expand Down
75 changes: 75 additions & 0 deletions docs/troubleshooting/hosting-startup-not-supported.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
title: HostingStartup is not supported with .NET Aspire integrations
description: Learn how to migrate from HostingStartup to the IHostApplicationBuilder pattern for use with .NET Aspire integrations.
ms.date: 08/04/2025
---

# HostingStartup is not supported with .NET Aspire integrations

.NET Aspire integrations require the use of <xref:Microsoft.Extensions.Hosting.IHostApplicationBuilder>, but `HostingStartup` only provides access to <xref:Microsoft.AspNetCore.Hosting.IWebHostBuilder>. This fundamental incompatibility means that you can't configure .NET Aspire integrations from within a `HostingStartup` implementation.

## Symptoms

When attempting to use .NET Aspire integrations within a HostingStartup implementation, you might encounter:

- **Compilation errors**: Aspire integration extension methods like `AddNpgsqlDbContext` or `AddRedis` are not available on `IWebHostBuilder`.
- **Runtime configuration issues**: Even if you access the underlying services, the proper configuration and service registration won't occur.
- **Missing telemetry and resilience**: Aspire's built-in observability, health checks, and resilience patterns won't be applied.

## Why HostingStartup doesn't work with .NET Aspire

.NET Aspire integrations extend <xref:Microsoft.Extensions.Hosting.IHostApplicationBuilder> to provide:

- Standardized configuration patterns
- Built-in health checks
- Telemetry and observability
- Resilience patterns
- Service discovery integration

The `HostingStartup` feature was designed for the older ASP.NET Core hosting model and only provides access to <xref:Microsoft.AspNetCore.Hosting.IWebHostBuilder>, which doesn't include these modern hosting capabilities.

## Migration strategies

### Option 1: Use IHostApplicationBuilder directly (Recommended)

Instead of using `HostingStartup`, configure your application directly in the `Program.cs` file using the modern hosting pattern:

**Before (HostingStartup pattern):**

:::code language="csharp" source="snippets/hosting-startup-not-supported/hosting-startup-before.cs":::

**After (IHostApplicationBuilder pattern):**

:::code language="csharp" source="snippets/hosting-startup-not-supported/host-application-builder-after.cs":::

### Option 2: Create configuration extensions

If you need modular configuration, create extension methods that work with `IHostApplicationBuilder`:

:::code language="csharp" source="snippets/hosting-startup-not-supported/configuration-extensions.cs":::

### Option 3: Use feature flags or configuration-based service registration

For conditional service registration based on configuration:

:::code language="csharp" source="snippets/hosting-startup-not-supported/feature-flags-configuration.cs":::

## Best practices for modular configuration

1. **Use configuration-based decisions**: Instead of having separate startup classes, use configuration values to determine which services to register.

1. **Create extension methods**: Group related service registrations into extension methods on `IHostApplicationBuilder`.

1. **Leverage service defaults**: Always call `builder.AddServiceDefaults()` to get the full benefits of .NET Aspire's built-in features.

1. **Use the app host for orchestration**: For development scenarios, use the [.NET Aspire app host](../fundamentals/app-host-overview.md) to manage dependencies and configuration.

## Additional considerations

- **Service discovery**: .NET Aspire integrations automatically configure service discovery. If you were using HostingStartup for service-to-service communication, consider using Aspire's [service discovery features](../service-discovery/overview.md).

- **Configuration management**: Instead of hard-coding connection strings in HostingStartup, use .NET Aspire's configuration patterns with connection string names that map to resources in your app host.

- **Testing**: .NET Aspire provides [testing capabilities](../testing/overview.md) that work with the new hosting model.

For more information about .NET Aspire integrations and the hosting model, see [.NET Aspire integrations overview](../fundamentals/integrations-overview.md).
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// DatabaseConfiguration.cs
public static class DatabaseConfiguration
{
public static IHostApplicationBuilder AddDatabaseServices(
this IHostApplicationBuilder builder)
{
// Configure your database based on environment or configuration
var connectionName = builder.Configuration["DatabaseProvider"] switch
{
"PostgreSQL" => "postgres",
"SqlServer" => "sqlserver",
_ => throw new InvalidOperationException("Unsupported database provider")
};

builder.AddNpgsqlDbContext<MyDbContext>(connectionName);

return builder;
}
}

// Program.cs
var builder = WebApplication.CreateBuilder(args);

Check failure on line 22 in docs/troubleshooting/snippets/hosting-startup-not-supported/configuration-extensions.cs

View workflow job for this annotation

GitHub Actions / snippets-build

/home/runner/work/docs-aspire/docs-aspire/docs/troubleshooting/snippets/hosting-startup-not-supported/configuration-extensions.cs(22,1): error CS8803: Top-level statements must precede namespace and type declarations. [/home/runner/work/docs-aspire/docs-aspire/docs/troubleshooting/snippets/hosting-startup-not-supported/hosting-startup-not-supported.csproj]
builder.AddServiceDefaults();
builder.AddDatabaseServices(); // Your modular configuration
var app = builder.Build();
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();

// Conditional service registration based on configuration
var databaseProvider = builder.Configuration["DatabaseProvider"];
switch (databaseProvider)
{
case "PostgreSQL":
builder.AddNpgsqlDbContext<MyDbContext>("postgres");
break;
case "SqlServer":
builder.AddSqlServerDbContext<MyDbContext>("sqlserver");
break;
default:
throw new InvalidOperationException($"Unsupported database provider: {databaseProvider}");
}

var telemetryProvider = builder.Configuration["TelemetryProvider"];
switch (telemetryProvider)
{
case "ApplicationInsights":
builder.Services.AddApplicationInsightsTelemetry();
break;
case "OpenTelemetry":
// OpenTelemetry is included with service defaults
break;
}

var app = builder.Build();
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Program.cs
var builder = WebApplication.CreateBuilder(args);

// Add service defaults first
builder.AddServiceDefaults();

// Now you can use Aspire integrations
builder.AddNpgsqlDbContext<MyDbContext>("postgres");

var app = builder.Build();

app.MapDefaultEndpoints();
app.Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// MyDatabaseStartup.cs
public class MyDatabaseStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
// This won't work with Aspire integrations
services.AddDbContext<MyDbContext>(options =>
options.UseNpgsql(connectionString));
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
Loading