feat: Add Aspire starter project scaffolding#4
Conversation
- Create AppHost orchestrator (Aspire host) - Create ServiceDefaults (shared infrastructure) - Create Api project (Minimal APIs + vertical slices) - Create Web project (Blazor Server UI) - Set up Central Package Management (Directory.Packages.props) - Configure global.json for .NET 10 - Add architectural decisions and quality validation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation. |
There was a problem hiding this comment.
Pull request overview
This PR introduces the foundational Aspire starter project structure for the IssueManager application, implementing a modern .NET architecture with service orchestration. It establishes the basic scaffolding for a distributed application using .NET 10 and C# 14.0, with MongoDB as the data store and Blazor for the frontend.
Changes:
- Created four-project Aspire architecture: AppHost (orchestrator), ServiceDefaults (shared infrastructure), Api (backend), and Web (frontend)
- Configured Central Package Management (CPM) via Directory.Packages.props for consistent dependency versioning
- Set up MongoDB resource in AppHost and established project references between services
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| Directory.Packages.props | Implements CPM with centralized package versions for Aspire, OpenTelemetry, MongoDB, Scalar, and testing packages |
| IssueManager.slnx | Adds all four new projects to the solution manifest |
| global.json | Pins .NET SDK to version 10.0.200-preview |
| src/AppHost/AppHost.csproj | Defines orchestrator project with Aspire hosting packages |
| src/AppHost/Program.cs | Configures MongoDB resource and project references for api and web services |
| src/ServiceDefaults/ServiceDefaults.csproj | Defines shared infrastructure library with OpenTelemetry and service discovery |
| src/ServiceDefaults/Extensions.cs | Provides extension methods for service defaults and health checks configuration |
| src/Api/Api.csproj | Defines minimal API project with OpenAPI, Scalar, and MongoDB support |
| src/Api/Program.cs | Implements sample weather forecast API endpoint with health checks |
| src/Web/Web.csproj | Defines Blazor Server web project |
| src/Web/Program.cs | Configures Blazor with interactive server rendering and antiforgery protection |
| src/Web/App.razor | Defines root Blazor application component with HTML structure |
| src/Web/Routes.razor | Configures routing for Blazor pages |
| src/Web/_Imports.razor | Defines common Razor imports for the Web project |
| src/Web/Layout/MainLayout.razor | Implements main layout with sidebar and navigation |
| src/Web/Layout/NavMenu.razor | Provides navigation menu component |
| src/Web/Pages/Home.razor | Implements home page with welcome message |
| src/Web/wwwroot/app.css | Provides custom CSS styling (should use Tailwind per guidelines) |
Comments suppressed due to low confidence (16)
src/Web/Layout/MainLayout.razor:25
- The MainLayout implements IAsyncDisposable with an empty DisposeAsync method that only returns Task.CompletedTask. If there are no async cleanup operations needed, this implementation is unnecessary and should be removed. If async disposal will be needed in the future, consider adding a comment explaining the intended use.
async ValueTask IAsyncDisposable.DisposeAsync()
{
await Task.CompletedTask;
}
src/Web/Layout/NavMenu.razor:21
- The @code block is empty and serves no purpose. Remove empty code blocks to keep the component clean and maintainable, or add a comment if this is a placeholder for future functionality.
@code {
}
src/Web/Layout/NavMenu.razor:21
- According to the coding guidelines, Blazor components should have a "Component" suffix. The file should be renamed from "NavMenu.razor" to "NavMenuComponent.razor" to follow the established naming convention for Blazor components.
@namespace IssueManager.Web.Layout
<div class="navbar navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">IssueManager</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link" href="">Home</a>
</li>
</ul>
</div>
</div>
</div>
@code {
}
src/ServiceDefaults/Extensions.cs:26
- The AddDefaultHealthChecks extension method is defined but never invoked in the AddServiceDefaults method. According to the coding guidelines, health checks are required. Consider calling AddDefaultHealthChecks() inside AddServiceDefaults to ensure all services have default health check configuration, or remove this unused method if health checks will be configured elsewhere.
/// <summary>
/// Adds default health check configuration.
/// </summary>
public static IHealthChecksBuilder AddDefaultHealthChecks(this IServiceCollection services)
{
return services.AddHealthChecks();
}
src/Web/Pages/Home.razor:12
- The @code block is empty and serves no purpose. Remove empty code blocks to keep the component clean and maintainable, or add a comment if this is a placeholder for future functionality.
@code {
}
src/Web/wwwroot/app.css:56
- According to the coding guidelines, Tailwind CSS should be used for styling. The app.css file contains custom CSS instead of Tailwind utility classes. Consider replacing this custom CSS with Tailwind configuration and utility classes, or update the project to include Tailwind CSS setup (tailwind.config.js, PostCSS, etc.).
html, body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
margin: 0;
padding: 0;
}
body {
background-color: #f5f5f5;
}
.page {
display: flex;
height: 100vh;
}
.sidebar {
width: 250px;
background-color: #f8f9fa;
border-right: 1px solid #dee2e6;
overflow-y: auto;
}
main {
flex: 1;
overflow-y: auto;
}
.content {
max-width: 1200px;
padding: 2rem;
}
.top-row {
background-color: #fff;
border-bottom: 1px solid #dee2e6;
padding: 1rem;
}
.top-row a {
color: #007bff;
text-decoration: none;
}
.top-row a:hover {
text-decoration: underline;
}
h1 {
color: #212529;
margin-top: 0;
}
p {
color: #6c757d;
line-height: 1.6;
}
src/Api/Program.cs:7
- According to the coding guidelines, OpenTelemetry is required for structured logging and observability. The Api project should call builder.Services.AddOpenTelemetry() to configure telemetry collection. Consider adding this before the AddOpenApi call to ensure proper instrumentation of the API.
builder.Services.AddServiceDefaults();
builder.Services.AddOpenApi();
src/Api/Program.cs:36
- According to the coding guidelines, XML documentation comments are required. The WeatherForecast record should have a summary tag explaining its purpose, and its properties should be documented. Add XML documentation to ensure consistency with project standards.
internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
src/Api/Api.csproj:15
- The Api.csproj references MongoDB.Entities, but the Api/Program.cs doesn't configure or use MongoDB. Additionally, the AppHost passes a MongoDB reference to the api project, but it's not being consumed. Either configure MongoDB connection and initialization in the Api startup, or remove the unused MongoDB.Entities package reference if it's not needed yet.
<PackageReference Include="MongoDB.Entities" />
src/ServiceDefaults/Extensions.cs:18
- The ServiceDefaults project should configure OpenTelemetry for structured logging and observability as required by the coding guidelines. Add methods to configure logging, tracing, and metrics using the OpenTelemetry packages that are referenced. The AddServiceDefaults method should orchestrate these configurations.
public static IServiceCollection AddServiceDefaults(this IServiceCollection services)
{
services.AddServiceDiscovery();
return services;
}
src/Web/App.razor:13
- The App.razor component should include a HeadOutlet component in the head section to allow child components and pages to dynamically inject content into the document head (such as meta tags, additional stylesheets, or scripts). Add HeadOutlet inside the head element for proper Blazor functionality.
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="IssueManager.Web.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
</head>
src/Api/Program.cs:12
- According to the coding guidelines, Scalar is required for API documentation instead of Swagger UI. While the Api.csproj includes the Scalar.AspNetCore package, the application is not configured to use Scalar. After MapOpenApi, add app.MapScalarApiReference() to enable the Scalar interactive API documentation interface.
app.MapOpenApi();
src/Web/Program.cs:21
- According to the coding guidelines, output caching is required. The Web project should call builder.Services.AddOutputCache() and app.UseOutputCache() to enable response caching for improved performance. Add this configuration before mapping Razor components.
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
src/Web/Pages/Home.razor:12
- According to the coding guidelines, Blazor pages should have a "Page" suffix. The file should be renamed from "Home.razor" to "HomePage.razor" to follow the established naming convention for Blazor pages.
@namespace IssueManager.Web.Pages
@page "/"
<PageTitle>Home</PageTitle>
<h1>Welcome to IssueManager</h1>
<p>This application demonstrates modern .NET architecture patterns with Aspire, Blazor, and MongoDB.</p>
@code {
}
src/Api/Program.cs:12
- According to the coding guidelines, output caching is required. The Api project should call builder.Services.AddOutputCache() and app.UseOutputCache() to enable response caching and improve performance. Consider adding this before mapping endpoints.
app.UseHttpsRedirection();
app.MapOpenApi();
src/Web/Layout/MainLayout.razor:17
- According to the coding guidelines, error boundaries are required. The MainLayout should wrap the @Body content with an ErrorBoundary component to gracefully handle component errors and display appropriate error UI. Add ErrorBoundary around the article content to catch and handle rendering exceptions.
<article class="content px-4">
@Body
</article>
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Aspire.Hosting.AppHost" /> |
There was a problem hiding this comment.
The Api project should not reference the Aspire.Hosting.AppHost package. This package is intended for orchestrator projects (like AppHost) that manage service topology. API services should not include this dependency. Remove this PackageReference from the Api project.
| <PackageReference Include="Aspire.Hosting.AppHost" /> |
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Aspire.Hosting" /> |
There was a problem hiding this comment.
The ServiceDefaults project should not reference the Aspire.Hosting package. ServiceDefaults is a shared library for configuring individual services, not an orchestrator. This package is only needed in the AppHost project. Remove this PackageReference from the ServiceDefaults project.
| <PackageReference Include="Aspire.Hosting" /> |
| builder.Services.AddOpenApi(); | ||
|
|
||
| var app = builder.Build(); | ||
|
|
||
| app.UseHttpsRedirection(); |
There was a problem hiding this comment.
According to the coding guidelines, antiforgery tokens are required for security. The Api project should call builder.Services.AddAntiforgery() and app.UseAntiforgery() to protect against CSRF attacks, especially if the API will be consumed by the Blazor Web frontend.
| builder.Services.AddOpenApi(); | |
| var app = builder.Build(); | |
| app.UseHttpsRedirection(); | |
| builder.Services.AddOpenApi(); | |
| builder.Services.AddAntiforgery(); | |
| var app = builder.Build(); | |
| app.UseHttpsRedirection(); | |
| app.UseAntiforgery(); |
| <PackageReference Include="Aspire.Hosting.AppHost" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectCapability Include="CanEvaluateItemsWithTargetFramework" /> | ||
| </ItemGroup> | ||
|
|
There was a problem hiding this comment.
The Web project should not reference the Aspire.Hosting.AppHost package. This package is intended for orchestrator projects (like AppHost) that manage service topology. Blazor web applications should not include this dependency. Remove this PackageReference from the Web project.
| <PackageReference Include="Aspire.Hosting.AppHost" /> | |
| </ItemGroup> | |
| <ItemGroup> | |
| <ProjectCapability Include="CanEvaluateItemsWithTargetFramework" /> | |
| </ItemGroup> | |
| <ProjectCapability Include="CanEvaluateItemsWithTargetFramework" /> | |
| </ItemGroup> |
Closes #3
Scaffolded the Aspire starter project with:
All projects target .NET 10 with C# 14.0 language features.