feat!: modernize host setup API with ASP.NET Core minimal API pattern#2076
feat!: modernize host setup API with ASP.NET Core minimal API pattern#2076
Conversation
BREAKING CHANGE: Replace PipelineHostBuilder with new PipelineBuilder API
This is a complete redesign of the pipeline configuration API to follow
ASP.NET Core's WebApplicationBuilder pattern:
Before (callback-based):
await PipelineHostBuilder.Create()
.ConfigureServices((context, services) => { services.AddModule<MyModule>(); })
.ConfigurePipelineOptions((context, options) => { })
.ExecutePipelineAsync();
After (direct property access):
var builder = Pipeline.CreateBuilder();
builder.Services.AddModule<MyModule>();
builder.Options.DefaultRetryCount = 3;
await builder.Build().RunAsync();
Changes:
- New Pipeline.CreateBuilder() static factory method
- New PipelineBuilder with direct property access (Services, Configuration, Options)
- New IPipeline interface for built pipelines (replaces IPipelineHost)
- New PipelineBuilderExtensions for convenience methods (AddModule, ConfigureServices)
- Remove PipelineHostBuilder, PipelineHost, IPipelineHost
- Remove callback-based configuration methods
- Update all examples and tests to use new API
Closes #2065
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SummaryRedesigns the pipeline configuration API from callback-based PipelineHostBuilder to a direct property access pattern (PipelineBuilder) following ASP.NET Core's WebApplicationBuilder pattern. Critical Issues1. CRITICAL: Finalizer calling async disposal synchronously In ~PipelineImpl()
{
DisposeAsync().AsTask().GetAwaiter().GetResult();
}Problem: Calling Recommendation: Follow the standard pattern - finalizers should only dispose unmanaged resources. Remove the finalizer entirely since this class only manages managed resources (IHost, AsyncServiceScope), or implement IDisposable with a proper dispose pattern that tracks whether async disposal has occurred. Previous implementation (PipelineHost.cs): ~PipelineHost()
{
Dispose(); // Called non-async Dispose()
}
public void Dispose()
{
#pragma warning disable CS4014
DisposeAsync(); // Fire and forget - also problematic but different
#pragma warning restore CS4014
}The old implementation was also problematic (fire-and-forget), but the new one is worse (blocking). Best practice: remove finalizer for managed-only resources. 2. CRITICAL: Build() synchronously blocks on async initialization In public IPipeline Build()
{
return BuildPipelineAsync().GetAwaiter().GetResult();
}Problem: Recommendation: Either:
The example in var pipeline = builder.Build(); // Synchronous
await pipeline.RunAsync();Should be: var pipeline = await builder.BuildAsync(); // Preferred
await pipeline.RunAsync();Suggestions1. Inconsistent naming: BuildAsync() vs BuildPipelineAsync()
2. Consider exposing PipelineBuilderOptions The Previous Review StatusNo previous comments found. Verdict |
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SummaryThis PR redesigns the pipeline configuration API from a callback-based pattern to direct property access, following ASP.NET Core WebApplicationBuilder pattern. Critical IssuesNone found ObservationsPositive Changes
Minor Observations
Questions
VerdictAPPROVE - Well-executed API modernization with clear breaking change documentation |
Summary
PipelineHostBuilderwith newPipelineBuilderthat exposesServices,Configuration, andOptionsdirectlyBreaking Changes
The entire host setup API has been replaced:
Before (callback-based):
After (direct property access):
Changes
New API
Pipeline.CreateBuilder()- Static factory method (like WebApplication.CreateBuilder())PipelineBuilder- Builder with direct property access:.Services- IServiceCollection for DI registration.Configuration- ConfigurationManager for configuration sources.Options- PipelineOptions for pipeline settings.Environment- IHostEnvironment for environment infoIPipeline- Interface for built pipelines (replaces IPipelineHost)PipelineBuilderExtensions- Convenience methods likeAddModule<T>(),ConfigureServices(), etc.Removed
PipelineHostBuilderclassPipelineHostclassIPipelineHostinterfaceHostExtensionsclassTest Plan
ModularPipelines.Build) works correctlyCloses #2065
🤖 Generated with Claude Code