MIGRATION-PLAN.md
Generated: 2026-03-06
Status: Ready for Execution
Estimated Time: 3.5 hours
Total Commits: 13 (12 samples + 1 documentation)
This plan addresses 13 outdated samples identified in OUT-OF-DATE.md, migrating them to use modern .NET 10 APIs.
| Priority | Category | Samples | Effort |
|---|---|---|---|
| HIGH | Swashbuckle → Built-in OpenAPI | 10 | 2 hours |
| HIGH | Manual SSE → Built-in SSE | 1 | 15 min |
| MEDIUM | NSwag → Built-in OpenAPI (MVC) | 1 | 15 min |
| MEDIUM | Custom IHostedService → BackgroundService | 1 | 15 min |
| FINAL | Documentation updates | 1 | 30 min |
git status should show clean working directory# Option 1: Work on main (if you have push access)
git checkout main
git pull origin main
# Option 2: Create feature branch (recommended)
git checkout -b migrate-to-net10-patterns
Follow this order for best results:
Phase 1: OpenAPI Samples (10 samples, ~2 hours)
open-api-1 (establishes pattern)open-api-2, then map-group-*, map-4pokedex, authentication-* samplesnswag and nswag-2Phase 2: SSE Sample (1 sample, ~15 min)
sse to use Results.ServerSentEvents()Phase 3: IHostedService Sample (1 sample, ~15 min)
ihosted-service-1 to use BackgroundServicePhase 4: Documentation (1 commit, ~30 min)
Follow this workflow:
# 1. Navigate to sample
cd projects/<category>/<sample-name>
# 2. Read current implementation
cat Program.cs
cat <sample-name>.csproj
cat README.md
# 3. Make changes (see Migration Patterns below)
# - Update .csproj
# - Update Program.cs
# - Update README.md
# 4. Test thoroughly
dotnet build
dotnet watch run
# Test in browser (see Testing Checklist)
# 5. Stop the app (Ctrl+C)
# 6. Return to root
cd /mnt/d/GitHub/practical-aspnetcore
# 7. Review changes
git status
git diff projects/<category>/<sample-name>/
# 8. Stage changes
git add projects/<category>/<sample-name>/
# 9. Commit with message (see Commit Messages below)
git commit -m "..."
# 10. Verify commit
git log -1 --stat
# 11. Repeat for next sample
Applies to: open-api-1, open-api-2, map-group-2, map-group-3, map-4, pokedex, authentication-4, authentication-5, nswag, nswag-2
Location: projects/<category>/<sample-name>/<sample-name>.csproj
Remove:
<PackageReference Include="Swashbuckle.AspNetCore" Version="..." />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.x" />
<PackageReference Include="NSwag.AspNetCore" Version="..." />
Add:
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>true</ImplicitUsings>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.5.*" />
<PackageReference Include="Scalar.AspNetCore" Version="2.1.13" />
</ItemGroup>
Location: projects/<category>/<sample-name>/Program.cs
Add at top:
using Scalar.AspNetCore;
Remove:
// These using statements
using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi.Models;
// Service registration
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(setup => setup.SwaggerDoc("v1", new OpenApiInfo() { ... }));
// Middleware
app.UseSwagger();
app.UseSwaggerUI();
// For NSwag samples
builder.Services.AddSwaggerDocument(settings => { ... });
app.UseOpenApi();
app.UseSwaggerUi(settings => { ... });
// Extension method on endpoints
.WithOpenApi(op =>
{
op.OperationId = "...";
op.Summary = "...";
return op;
});
Add:
// Service registration (after other services)
builder.Services.AddOpenApi();
// Middleware (after app.Build(), before endpoints)
app.MapOpenApi();
app.MapScalarApiReference();
Replace .WithOpenApi() with XML comments:
// BEFORE
app.MapGet("/greeting", Hello.GetGreeting).WithOpenApi(op =>
{
op.OperationId = "GetGreetings";
op.Summary = "Return greeting given name";
return op;
});
// AFTER
/// <summary>
/// Return greeting given name
/// </summary>
/// <param name="name">The name of the person to greet</param>
app.MapGet("/greeting", Hello.GetGreeting);
For MVC controllers (NSwag samples):
// Add XML comments to controller actions:
/// <summary>
/// Returns a hello world message
/// </summary>
/// <response code="200">The greeting message</response>
[HttpGet("")]
public ActionResult<Greeting> Index()
{
return new Greeting { Message = "Hello World" };
}
Location: projects/<category>/<sample-name>/README.md
Replace content with:
# Built-in OpenAPI with Scalar UI
This sample demonstrates ASP.NET Core 10's built-in OpenAPI 3.1 support.
## Key Features
- No external packages required (Swashbuckle/NSwag removed)
- OpenAPI 3.1 document generated automatically
- XML doc comments populate API descriptions
- Modern Scalar UI for interactive documentation
- AOT-compatible
## Running the Sample
```bash
dotnet watch run
/scalar/openapi/v1.jsonThis sample was migrated from Swashbuckle to .NET 10's built-in OpenAPI support.
Changes:
Swashbuckle.AspNetCore package dependencyMicrosoft.AspNetCore.OpenApi (built-in)Scalar.AspNetCore for modern UIWithOpenApi() with XML documentation commentsGenerateDocumentationFile in .csprojSee OUT-OF-DATE.md for migration details.
**For NSwag samples, adjust to mention NSwag:**
```markdown
# Built-in OpenAPI with MVC Controllers
This sample demonstrates ASP.NET Core 10's built-in OpenAPI support with MVC controllers.
## Migration Notes
This sample was migrated from NSwag to .NET 10's built-in OpenAPI support.
Applies to: sse
Location: projects/sse/Program.cs
Add at top:
using System.Runtime.CompilerServices;
Replace the entire /sse endpoint (lines 6-38) with:
app.MapGet("/sse", (HttpContext context, CancellationToken cancellationToken) =>
{
async IAsyncEnumerable<string> CounterAsync([EnumeratorCancellation] CancellationToken ct)
{
int count = 0;
while (!ct.IsCancellationRequested)
{
yield return $"hello world {++count}";
await Task.Delay(3000, ct);
}
}
if (context.Request.Headers.Accept == "text/event-stream")
{
return Results.ServerSentEvents(CounterAsync(cancellationToken), eventType: "message");
}
else
{
return Results.BadRequest("Unsupported Accept header. Use 'text/event-stream'.");
}
});
Remove the Counter() method at the bottom (lines 69-76) - no longer needed
Location: projects/sse/README.md
Replace content with:
# Built-in Server-Sent Events
This sample demonstrates ASP.NET Core 10's built-in Server-Sent Events (SSE) support using `Results.ServerSentEvents()`.
## Running the Sample
```bash
dotnet watch run
Navigate to http://localhost:5000/ to see the SSE client in action.
Results.ServerSentEvents()IAsyncEnumerable<T>The endpoint returns Results.ServerSentEvents() with an IAsyncEnumerable<string>:
app.MapGet("/sse", (HttpContext context, CancellationToken cancellationToken) =>
{
async IAsyncEnumerable<string> CounterAsync([EnumeratorCancellation] CancellationToken ct)
{
int count = 0;
while (!ct.IsCancellationRequested)
{
yield return $"hello world {++count}";
await Task.Delay(3000, ct);
}
}
if (context.Request.Headers.Accept == "text/event-stream")
{
return Results.ServerSentEvents(CounterAsync(cancellationToken), eventType: "message");
}
return Results.BadRequest("Use Accept: text/event-stream");
});
This sample was migrated from manual SSE implementation to .NET 10's built-in support.
Changes:
Response.WriteAsync() and FlushAsync() callsResults.ServerSentEvents() with IAsyncEnumerable<string>[EnumeratorCancellation]See OUT-OF-DATE.md for migration details.
projects/net10/sse-2/ - Basic SSEprojects/net10/sse-3/ - SSE with event typesprojects/net10/sse-4/ - SSE with mixed events using SseItem<T>
---
### Pattern C: IHostedService Migration (Custom → BackgroundService)
**Applies to:** `ihosted-service-1`
#### Step 1: Update Program.cs
**Location:** `projects/ihosted-service/ihosted-service-1/Program.cs`
**Add at top:**
```csharp
using Microsoft.Extensions.Hosting;
Remove the entire HostedService abstract class (lines 15-51)
Replace the GreeterUpdaterService class (lines 53-69) with:
public class GreeterUpdaterService : BackgroundService
{
private readonly Greeter _greeter;
public GreeterUpdaterService(Greeter greeter)
{
_greeter = greeter;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_greeter.Counter++;
await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
}
}
}
Update the service registration (line 3):
// BEFORE
builder.Services.AddSingleton<Microsoft.Extensions.Hosting.IHostedService, GreeterUpdaterService>();
// AFTER
builder.Services.AddHostedService<GreeterUpdaterService>();
Location: projects/ihosted-service/ihosted-service-1/README.md
Replace content with:
# BackgroundService Pattern
This sample demonstrates using the `BackgroundService` base class for background tasks in ASP.NET Core.
## Running the Sample
```bash
dotnet watch run
Navigate to http://localhost:5000/ and reload the page to see the counter incrementing.
A GreeterUpdaterService inherits from BackgroundService and updates a Greeter singleton every second:
public class GreeterUpdaterService : BackgroundService
{
private readonly Greeter _greeter;
public GreeterUpdaterService(Greeter greeter)
{
_greeter = greeter;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_greeter.Counter++;
await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
}
}
}
builder.Services.AddSingleton<Greeter>();
builder.Services.AddHostedService<GreeterUpdaterService>();
This sample was simplified from a custom IHostedService implementation to using the built-in BackgroundService base class.
Changes:
HostedService abstract base class (40+ lines of boilerplate)Microsoft.Extensions.Hosting.BackgroundServiceBenefits:
BackgroundService handles all the boilerplateMicrosoft.Extensions.HostingSee OUT-OF-DATE.md for migration details.
---
## Testing Checklist
### For OpenAPI Samples
**Before each commit, verify:**
```bash
# 1. Build succeeds
cd projects/<category>/<sample-name>
dotnet build
# Should see: Build succeeded. 0 Warning(s). 0 Error(s).
# 2. Run succeeds
dotnet watch run
# Should see: Now listening on: http://localhost:5000
# 3. Test in browser
# Open browser to http://localhost:5000/scalar
# - Scalar UI should load
# - Endpoints should be listed
# - Click on endpoint, should see parameters and descriptions
# 4. Test OpenAPI document
# Navigate to http://localhost:5000/openapi/v1.json
# - Should see valid JSON
# - Should include endpoint descriptions from XML comments
# 5. Stop the app
# Press Ctrl+C in terminal
# 6. Return to root
cd /mnt/d/GitHub/practical-aspnetcore
Common issues:
GenerateDocumentationFile in .csprojScalar.AspNetCore package is installedbuilder.Services.AddOpenApi() is called# 1. Build and run
cd projects/sse
dotnet build
dotnet watch run
# 2. Test in browser
# Navigate to http://localhost:5000/
# - Page should load with empty list
# - Open browser console (F12)
# - Should see: "Connecting to SSE..."
# - Should see: "Connection opened:"
# - List items should appear every 3 seconds
# - Each item should say "hello world X"
# 3. Stop the app
# Press Ctrl+C
# 4. Return to root
cd /mnt/d/GitHub/practical-aspnetcore
# 1. Build and run
cd projects/ihosted-service/ihosted-service-1
dotnet build
dotnet watch run
# 2. Test in browser
# Navigate to http://localhost:5000/
# - Should see: "Please reload page (greeting updated every 1 second in the background) Hello world 0"
# - Reload the page
# - Counter should have incremented
# - Example: "Hello world 5" (if 5 seconds passed)
# 3. Stop the app
# Press Ctrl+C
# 4. Return to root
cd /mnt/d/GitHub/practical-aspnetcore
<action> <sample-path> to .NET 10 <feature>
- <change 1>
- <change 2>
- <change 3>
Refs: OUT-OF-DATE.md - <category>
git commit -m "Migrate minimal-api/open-api-1 to .NET 10 built-in OpenAPI
- Replace Swashbuckle.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Remove deprecated WithOpenApi() extension method
- Add XML doc comments for endpoint descriptions
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
git commit -m "Migrate minimal-api/open-api-2 to .NET 10 built-in OpenAPI
- Replace Swashbuckle.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Remove deprecated WithOpenApi() extension method
- Add XML doc comments for endpoint descriptions and responses
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
git commit -m "Migrate minimal-api/map-group-2 to .NET 10 built-in OpenAPI
- Replace Swashbuckle.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
git commit -m "Migrate minimal-api/map-group-3 to .NET 10 built-in OpenAPI
- Replace Swashbuckle.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
git commit -m "Migrate minimal-api/map-4 to .NET 10 built-in OpenAPI
- Replace Swashbuckle.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
git commit -m "Migrate pokedex to .NET 10 built-in OpenAPI
- Replace Swashbuckle.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
git commit -m "Migrate authentication-4 to .NET 10 built-in OpenAPI
- Replace Swashbuckle.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
git commit -m "Migrate authentication-5 to .NET 10 built-in OpenAPI
- Replace Swashbuckle.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Remove deprecated WithOpenApi() extension method
- Add XML doc comments for endpoint descriptions
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
git commit -m "Migrate mvc/nswag to .NET 10 built-in OpenAPI with MVC
- Replace NSwag.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Add XML doc comments to controller actions
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
git commit -m "Migrate mvc/nswag-2 to .NET 10 built-in OpenAPI with MVC
- Replace NSwag.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Add XML doc comments to controller actions
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
git commit -m "Migrate sse sample to .NET 10 built-in Server-Sent Events
- Replace manual SSE protocol implementation with Results.ServerSentEvents()
- Use IAsyncEnumerable<string> with proper cancellation token handling
- Add [EnumeratorCancellation] attribute for proper cancellation
- Remove manual Response.WriteAsync() and FlushAsync() calls
- Simplify code with automatic flush management
- Update README.md with built-in SSE notes
Refs: OUT-OF-DATE.md - Category 2: Server-Sent Events"
git commit -m "Simplify ihosted-service-1 using BackgroundService base class
- Remove custom HostedService abstract base class (40+ lines of boilerplate)
- Inherit from Microsoft.Extensions.Hosting.BackgroundService
- Update service registration to use AddHostedService<T>()
- Cleaner cancellation token handling via stoppingToken parameter
- Update README.md with BackgroundService pattern notes
Refs: OUT-OF-DATE.md - Category 3: IHostedService Patterns"
git commit -m "Update documentation to reflect .NET 10 migrations
- Update root README.md with note about .NET 10 modern patterns
- Update projects/minimal-api/README.md with OpenAPI migration notes
- Update projects/authentication/README.md with OpenAPI migration notes
- Update projects/sse/README.md with built-in SSE notes
- Update projects/mvc/README.md with NSwag alternative notes
- Update projects/ihosted-service/README.md with BackgroundService pattern notes
- Mark OUT-OF-DATE.md as completed
Refs: OUT-OF-DATE.md"
Location: projects/minimal-api/open-api-1/
Files to update:
open-api-1.csprojProgram.csREADME.mdSteps:
cd projects/minimal-api/open-api-1
# Read current files
cat open-api-1.csproj
cat Program.cs
cat README.md
# Update .csproj (see Pattern A, Step 1)
# Update Program.cs (see Pattern A, Step 2)
# Update README.md (see Pattern A, Step 3)
# Test
dotnet build
dotnet watch run
# Test in browser: /scalar and /openapi/v1.json
# Press Ctrl+C to stop
cd /mnt/d/GitHub/practical-aspnetcore
# Commit
git add projects/minimal-api/open-api-1/
git commit -m "Migrate minimal-api/open-api-1 to .NET 10 built-in OpenAPI
- Replace Swashbuckle.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Remove deprecated WithOpenApi() extension method
- Add XML doc comments for endpoint descriptions
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
# Verify
git log -1 --stat
Location: projects/minimal-api/open-api-2/
Steps: Same as Sample 1, but use commit message for open-api-2
Location: projects/minimal-api/map-group-2/
Steps: Same as Sample 1, but use commit message for map-group-2
Location: projects/minimal-api/map-group-3/
Steps: Same as Sample 1, but use commit message for map-group-3
Location: projects/minimal-api/map-4/
Steps: Same as Sample 1, but use commit message for map-4
Location: projects/mini/minimal-api-pokedex/src/Minimal.Api.Pokedex/
Note: This is a multi-project sample. Update the main API project.
Steps:
cd projects/mini/minimal-api-pokedex/src/Minimal.Api.Pokedex
# Read current files
cat Minimal.Api.Pokedex.csproj
cat Program.cs
# Update .csproj and Program.cs using Pattern A
# Test
dotnet build
dotnet watch run
# Test in browser
# Press Ctrl+C
cd /mnt/d/GitHub/practical-aspnetcore
# Commit
git add projects/mini/minimal-api-pokedex/
git commit -m "Migrate pokedex to .NET 10 built-in OpenAPI
- Replace Swashbuckle.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
Location: projects/authentication/authentication-4/
Steps: Same as Sample 1, but use commit message for authentication-4
Location: projects/authentication/authentication-5/
Steps: Same as Sample 1, but use commit message for authentication-5
Location: projects/mvc/nswag/
Steps:
cd projects/mvc/nswag
# Read current files
cat nswag.csproj
cat Program.cs
# Update .csproj (see Pattern A, Step 1 - remove NSwag, add Scalar)
# Update Program.cs (see Pattern A, Step 2 - for MVC)
# Add XML comments to controller actions
# Test
dotnet build
dotnet watch run
# Test in browser: /scalar
# Press Ctrl+C
cd /mnt/d/GitHub/practical-aspnetcore
# Commit
git add projects/mvc/nswag/
git commit -m "Migrate mvc/nswag to .NET 10 built-in OpenAPI with MVC
- Replace NSwag.AspNetCore with Microsoft.AspNetCore.OpenApi 10.0.0-preview
- Add Scalar.AspNetCore for modern API documentation UI
- Add XML doc comments to controller actions
- Update .csproj: enable GenerateDocumentationFile
- Update README.md with built-in OpenAPI notes
Refs: OUT-OF-DATE.md - Category 1: Swashbuckle/OpenAPI Samples"
Location: projects/mvc/nswag-2/
Steps: Same as Sample 9, but use commit message for nswag-2
Location: projects/sse/
Steps:
cd projects/sse
# Read current file
cat Program.cs
# Update Program.cs (see Pattern B, Step 1)
# Update README.md (see Pattern B, Step 2)
# Test
dotnet build
dotnet watch run
# Test in browser: http://localhost:5000/
# Open console, verify SSE events
# Press Ctrl+C
cd /mnt/d/GitHub/practical-aspnetcore
# Commit
git add projects/sse/
git commit -m "Migrate sse sample to .NET 10 built-in Server-Sent Events
- Replace manual SSE protocol implementation with Results.ServerSentEvents()
- Use IAsyncEnumerable<string> with proper cancellation token handling
- Add [EnumeratorCancellation] attribute for proper cancellation
- Remove manual Response.WriteAsync() and FlushAsync() calls
- Simplify code with automatic flush management
- Update README.md with built-in SSE notes
Refs: OUT-OF-DATE.md - Category 2: Server-Sent Events"
Location: projects/ihosted-service/ihosted-service-1/
Steps:
cd projects/ihosted-service/ihosted-service-1
# Read current file
cat Program.cs
# Update Program.cs (see Pattern C, Step 1)
# Update README.md (see Pattern C, Step 2)
# Test
dotnet build
dotnet watch run
# Test in browser: http://localhost:5000/
# Reload page, counter should increment
# Press Ctrl+C
cd /mnt/d/GitHub/practical-aspnetcore
# Commit
git add projects/ihosted-service/ihosted-service-1/
git commit -m "Simplify ihosted-service-1 using BackgroundService base class
- Remove custom HostedService abstract base class (40+ lines of boilerplate)
- Inherit from Microsoft.Extensions.Hosting.BackgroundService
- Update service registration to use AddHostedService<T>()
- Cleaner cancellation token handling via stoppingToken parameter
- Update README.md with BackgroundService pattern notes
Refs: OUT-OF-DATE.md - Category 3: IHostedService Patterns"
Location: Root and category READMEs
Steps:
# Update root README.md
# Add a section about .NET 10 modern patterns after the introduction
# Update category READMEs:
# - projects/minimal-api/README.md
# - projects/authentication/README.md
# - projects/sse/README.md
# - projects/mvc/README.md
# - projects/ihosted-service/README.md
# For each category README, add a note:
# "Note: Samples have been migrated to use .NET 10 built-in features. See MIGRATION-PLAN.md for details."
# Update or remove OUT-OF-DATE.md
# Option 1: Add at top: "STATUS: MIGRATION COMPLETED (2026-03-06)"
# Option 2: Delete the file
# Commit
git add README.md
git add projects/*/README.md
git add OUT-OF-DATE.md
git commit -m "Update documentation to reflect .NET 10 migrations
- Update root README.md with note about .NET 10 modern patterns
- Update projects/minimal-api/README.md with OpenAPI migration notes
- Update projects/authentication/README.md with OpenAPI migration notes
- Update projects/sse/README.md with built-in SSE notes
- Update projects/mvc/README.md with NSwag alternative notes
- Update projects/ihosted-service/README.md with BackgroundService pattern notes
- Mark OUT-OF-DATE.md as completed
Refs: OUT-OF-DATE.md"
# 1. Check commit history
git log --oneline -13
# Should see all 13 commits in reverse chronological order
# 2. Verify no uncommitted changes
git status
# Should say: "nothing to commit, working tree clean"
# 3. Optional: Build all migrated samples
cd projects/minimal-api/open-api-1 && dotnet build && cd ../../..
cd projects/minimal-api/open-api-2 && dotnet build && cd ../../..
cd projects/minimal-api/map-group-2 && dotnet build && cd ../../..
cd projects/minimal-api/map-group-3 && dotnet build && cd ../../..
cd projects/minimal-api/map-4 && dotnet build && cd ../../..
cd projects/mini/minimal-api-pokedex/src/Minimal.Api.Pokedex && dotnet build && cd ../../../../..
cd projects/authentication/authentication-4 && dotnet build && cd ../../..
cd projects/authentication/authentication-5 && dotnet build && cd ../../..
cd projects/mvc/nswag && dotnet build && cd ../..
cd projects/mvc/nswag-2 && dotnet build && cd ../..
cd projects/sse && dotnet build && cd ../..
cd projects/ihosted-service/ihosted-service-1 && dotnet build && cd ../../..
# 4. If using feature branch, push to remote
git push origin migrate-to-net10-patterns
# 5. If ready to merge to main
git checkout main
git merge migrate-to-net10-patterns
git push origin main
Before marking this migration as complete, verify:
dotnet build succeeds)dotnet watch run succeeds)/scalar and /openapi/v1.json accessible (10 samples)WithOpenApi() usage remainsSwashbuckle.AspNetCore or NSwag.AspNetCore packages remaingit log --oneline -13 shows all commitsgit status shows clean working treeSolution: Add using Microsoft.Extensions.Hosting; at top of Program.cs
Solution: Add to .csproj:
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Solution: Check that:
Scalar.AspNetCore package is installedapp.MapScalarApiReference(); is called after app.Build()/scalar (not /swagger)Solution: Check that:
builder.Services.AddOpenApi(); is calledapp.MapOpenApi(); is calledSolution: Check that:
using System.Runtime.CompilerServices; is added[EnumeratorCancellation] attribute is on the cancellation token parameterAccept: text/event-stream headerSolution:
dotnet restorebin/ and obj/ folders and rebuildOUT-OF-DATE.md - Original analysis of outdated samplesprojects/net10/README.md - .NET 10 feature samples indexprojects/net10/open-api-8/ - Reference for built-in OpenAPI patternprojects/net10/sse-2/ - Reference for built-in SSE patternAGENTS.md - Repository conventions and guidelinesThis plan is self-contained - All information needed to execute the migration is in this file.
Follow the order - Execute samples in the order listed (1-13) for best results.
Test before commit - Always run dotnet build and dotnet watch run before committing.
Use the exact commit messages - Copy-paste the commit messages to ensure consistency.
One sample at a time - Don't try to batch multiple samples in one commit.
Reference existing .NET 10 samples - If unsure, look at projects/net10/open-api-8/ or projects/net10/sse-2/ for patterns.
Keep it simple - The goal is to demonstrate modern patterns with minimal code.
Update READMEs - Don't skip updating README.md files - they help users understand the changes.
Mark complete - After finishing, update this file with completion status.
When finished, update this section:
Notes: (Add any notes about issues encountered, deviations from plan, etc.)
End of Migration Plan