-
-
Notifications
You must be signed in to change notification settings - Fork 254
Add support for aspire in bit Boilerplate (#11033) #11034
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis update introduces comprehensive support for the "aspire" feature in the bit Boilerplate project template. It adds new configuration options, shared code, and conditional logic to enable Aspire hosting, shared services, and related infrastructure. Several files are refactored or reorganized to centralize shared logic, enhance modularity, and streamline service and middleware registration. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant TemplateEngine
participant AppHost
participant ServerWeb
participant ServerApi
participant Shared
User->>TemplateEngine: Create project (aspire=true/false)
TemplateEngine->>AppHost: Include/exclude AppHost project (if aspire)
TemplateEngine->>ServerWeb: Always include ServerWeb
TemplateEngine->>ServerApi: Include based on config
TemplateEngine->>Shared: Always include Shared
AppHost->>ServerWeb: Reference project
AppHost->>ServerApi: Reference project (conditionally)
AppHost->>Shared: Reference project
ServerWeb->>Shared: Reference project
ServerApi->>Shared: Reference project
Note over AppHost,Shared: Shared services, health checks, telemetry, and caching are centralized
Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Poem
✨ Finishing Touches🧪 Generate Unit Tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds optional Aspire support to the Bit Boilerplate template by centralizing shared server logic, introducing a ServerShared project, and updating templates and solution files to conditionally include Aspire components.
- Extract shared settings, middleware, and service registrations into
Boilerplate.Server.Shared - Introduce
aspiretemplate parameter and wire upMapAspire()andAddAspireServiceDefaults() - Update solution, project references, and template.json to include new shared and AppHost projects
Reviewed Changes
Copilot reviewed 33 out of 33 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| README.md | Updated DeepWiki link anchor |
| ServerWebSettings.cs | Removed in-project response caching and moved to shared settings |
| Program.*.cs | Removed duplicated CORS/compression/config from individual projects and delegated to AddServerSharedServices & Use* extensions |
| HttpRequestExtensions.cs / HttpContextExtensions.cs | Removed Web/API-specific extensions and moved core methods to shared extensions |
| Boilerplate.Server.Shared/** | New shared project containing common settings, extensions, policies, and service registrations |
| .template-config/template.json | Added aspire parameter and generated ports for AppHost |
| .sln | Updated solution and solution filter to include Server.Shared and Server.AppHost projects conditionally |
Comments suppressed due to low confidence (1)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/WebApplicationExtensions.cs:18
- Add automated tests or integration tests to verify that
MapAspire()registers the expected endpoints (e.g.,/health,/alive) only in development mode.
public static WebApplication MapAspire(this WebApplication app)
...late/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Services/AppResponseCachePolicy.cs
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Nitpick comments (3)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/appsettings.json (1)
3-12: Conditional markers break JSON tooling; consider a.templateextension or build-step rename
//#if …directives are perfectly valid for the dotnet-template engine, but they render the file invalid JSON everywhere else (IDE syntax highlighting, containerised linter pipelines, infra that expects valid JSON, etc.).
Two lightweight mitigations that keep template support intact:-// file keeps the .json extension +// rename to appsettings.json.template (or .json.tt)or add a pre-build copy task that renames it back to
appsettings.jsononly when the template engine has resolved the markers.This avoids the static-analysis noise you are already seeing in Biome.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.AppHost/Boilerplate.Server.AppHost.csproj (1)
3-10: DuplicateUserSecretsIdacross projects may leak secrets
UserSecretsIdis identical to the one in other server projects. Secrets written while developing the AppHost will therefore be visible to Api/Web and vice-versa, which defeats isolation and can surprise new contributors.-<UserSecretsId>AC87AA5B-4B37-4E52-8468-2D5DF24AF256</UserSecretsId> +<UserSecretsId>C4D6F3A0-...-UNIQUE-...</UserSecretsId>Generating a new GUID for each project is a one-time fix.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/HttpRequestExtensions.cs (1)
32-41: Consider expanding Lighthouse detection logic.The current detection only checks for "google" and "lighthouse" strings, which may miss other Lighthouse-related user agents or give false positives.
Consider a more specific detection pattern:
-public static bool IsLightHouseRequest(this HttpRequest request) -{ - var agent = GetLoweredUserAgent(request); - - if (agent.Contains("google")) return true; - - if (agent.Contains("lighthouse")) return true; - - return false; -} +public static bool IsLightHouseRequest(this HttpRequest request) +{ + var agent = GetLoweredUserAgent(request); + + // More specific Lighthouse detection + return agent.Contains("lighthouse") || + agent.Contains("chrome-lighthouse") || + (agent.Contains("google") && agent.Contains("lighthouse")); +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (33)
src/Templates/Boilerplate/Bit.Boilerplate/.template.config/template.json(4 hunks)src/Templates/Boilerplate/Bit.Boilerplate/Boilerplate.Web.slnf(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/Boilerplate.slnx(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Directory.Packages.props(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Boilerplate.Server.Api.csproj(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Extensions/HttpContextExtensions.cs(0 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Extensions/HttpRequestExtensions.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Program.Middlewares.cs(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Program.Services.cs(6 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Program.cs(0 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/ServerApiSettings.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Services/AppResponseCachePolicy.cs(0 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/appsettings.json(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.AppHost/Boilerplate.Server.AppHost.csproj(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.AppHost/Program.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.AppHost/Properties/launchSettings.json(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.AppHost/appsettings.Development.json(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.AppHost/appsettings.json(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Boilerplate.Server.Shared.csproj(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/HttpContextExtensions.cs(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/HttpRequestExtensions.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/WebApplicationBuilderExtensions.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/WebApplicationExtensions.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/ServerSharedSettings.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Services/AppResponseCachePolicy.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Boilerplate.Server.Web.csproj(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Components/App.razor(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Extensions/HttpRequestExtensions.cs(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Program.Middlewares.cs(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Program.Services.cs(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Program.cs(0 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/ServerWebSettings.cs(0 hunks)src/Websites/WikiDocs/README.md(1 hunks)
💤 Files with no reviewable changes (5)
- src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Program.cs
- src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Program.cs
- src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/ServerWebSettings.cs
- src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Extensions/HttpContextExtensions.cs
- src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Services/AppResponseCachePolicy.cs
🧰 Additional context used
🧬 Code Graph Analysis (6)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/HttpContextExtensions.cs (1)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Extensions/HttpContextExtensions.cs (1)
HttpContextExtensions(7-30)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Program.Services.cs (1)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/ServerWebSettings.cs (1)
ServerWebSettings(9-45)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/WebApplicationExtensions.cs (2)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/ServerSharedSettings.cs (1)
ServerSharedSettings(8-53)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Services/CultureInfoManager.cs (1)
CultureInfoManager(5-94)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/ServerApiSettings.cs (1)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/ServerSharedSettings.cs (1)
ServerSharedSettings(8-53)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Services/AppResponseCachePolicy.cs (1)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/ServerSharedSettings.cs (1)
ServerSharedSettings(8-53)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/HttpRequestExtensions.cs (3)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Extensions/HttpRequestExtensions.cs (2)
HttpRequestExtensions(5-28)Uri(12-27)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Extensions/HttpRequestExtensions.cs (1)
HttpRequestExtensions(3-29)src/BlazorUI/Bit.BlazorUI/Extensions/StringExtensions.cs (1)
HasValue(6-11)
🪛 Biome (1.9.4)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/appsettings.json
[error] 3-3: Expected a property but instead found '//#if (database == "SqlServer" && aspire == false)'.
Expected a property here.
(parse)
[error] 4-4: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 4-4: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 4-4: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 4-5: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 6-6: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 6-6: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 6-6: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 6-6: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 7-7: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 7-7: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 7-7: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 7-8: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 9-9: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 9-9: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 9-9: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 9-10: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
src/Templates/Boilerplate/Bit.Boilerplate/.template.config/template.json
[error] 165-165: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 165-165: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 165-171: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 171-171: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 274-274: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 274-274: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 274-282: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 282-282: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 283-283: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 283-283: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 283-291: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 291-291: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 292-292: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 292-292: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 292-300: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 300-300: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build and test
🔇 Additional comments (52)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Components/App.razor (1)
2-2: LGTM! Using directive aligns with shared extensions refactoring.The addition of
@using Microsoft.AspNetCore.Http;is appropriate given the HttpContext usage throughout the component and aligns with the move of HTTP extensions to the shared server project.src/Websites/WikiDocs/README.md (1)
45-45: LGTM! Documentation link update maintains accuracy.The anchor reference update aligns with changes to the referenced copilot-instructions.md file, ensuring the link remains functional.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.AppHost/appsettings.json (1)
1-9: LGTM! Standard logging configuration for Aspire hosting.The configuration appropriately reduces verbosity for framework-level logging while maintaining informational logs for application-level events, which is a best practice for Aspire host projects.
src/Templates/Boilerplate/Bit.Boilerplate/Boilerplate.Web.slnf (1)
7-11: LGTM! Proper conditional project inclusion for aspire feature.The solution file correctly implements conditional inclusion of the AppHost project when aspire is enabled, while unconditionally including the shared server project. The template syntax is properly formatted.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.AppHost/appsettings.Development.json (1)
1-8: LGTM! Appropriate development logging configuration.The development-specific logging configuration maintains informational level logs while reducing ASP.NET Core framework noise, which is suitable for development environments.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/appsettings.json (1)
3-12: Verify Aspire-first scenario still receives a usable connection stringWith
&& aspire == falsegates, none of the RDBMS connection strings are emitted when theaspireflag is on.
Please confirm that:
- The Aspire host really injects an equivalent connection string into the API process at runtime (via secrets, environment variables, or d-apr config), and
- No library code tries to read
Configuration["ConnectionStrings:SqlServerConnectionString"]when Aspire is enabled.If either condition fails you’ll hit
NullReference/InvalidOperationExceptionon firstDbContextconstruction.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Boilerplate.Server.Api.csproj (1)
87-88: 👍 Reference moved to the new shared projectThe new relative path resolves correctly from
Server.Api→Server.Shared. No other build-items reference the old location, so this looks safe.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.AppHost/Boilerplate.Server.AppHost.csproj (1)
21-24:<Using Remove="*"/>wipes ALL global usings – confirm this is intentionalRemoving the BCL defaults (
System,System.Collections.Generic, …) forces every file to add explicitusingdirectives, which can be verbose. If the goal is to avoid template pollution, consider:<Using Remove="Boilerplate.*" /> <!-- or any namespace prefix -->so standard usings remain intact.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Boilerplate.Server.Web.csproj (1)
25-28: Shared-project reference added – validate circular-dependency graph
Boilerplate.Server.Webnow depends onServer.Shared, which in turn references some Web-specific middleware. Double-check thatServer.Sharedhas no back-reference to Web to avoid cyclical rebuilds and unpredictable publish ordering.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.AppHost/Properties/launchSettings.json (1)
8-14: Port assignment / env-var names – quick sanity-check
- Ports
2030-2032are hard-coded. If multiple Aspire hosts are run in parallel (common in integration-test pipelines) they will collide. Consider0(dynamic) or template symbols.- Variable names match preview Aspire docs, but note that the final spec renamed
DOTNET_DASHBOARD_OTLP_ENDPOINT_URL→DOTNET_DASHBOARD_OTLP_URL.
A late RC/RTM change could break dashboards.Please verify against the SDK version you ship.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Program.Middlewares.cs (1)
20-22: LGTM! Good refactoring to use shared extension methods.The replacement of explicit middleware configuration with
UseAppForwardedHeaders()andUseLocalization()extension methods promotes code reuse and centralization of shared logic.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Boilerplate.Server.Shared.csproj (1)
1-27: LGTM! Well-structured shared project with appropriate dependencies.The project configuration is clean and follows best practices:
- Proper conditional logic for Aspire support
- Comprehensive OpenTelemetry instrumentation packages
- Conditional Application Insights inclusion
- Appropriate framework and project references
The dependency selection supports the centralization of telemetry, service discovery, and HTTP resilience patterns.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/HttpContextExtensions.cs (1)
7-23: LGTM! Appropriate visibility change for shared project.Changing the class and method visibility from
internaltopublicis correct for the shared project pattern, allowing these utility methods to be reused across multiple server projects while maintaining the same functionality.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Services/AppResponseCachePolicy.cs (2)
7-7: LGTM! Namespace change aligns with shared project structure.The namespace change from
Boilerplate.Server.Web.ServicestoBoilerplate.Server.Shared.Servicescorrectly reflects the migration to the shared project.
12-12: LGTM! Constructor parameter update supports shared configuration.The change from
ServerWebSettingstoServerSharedSettingsaligns with the centralization of shared configuration. Based on the relevant code snippet,ServerSharedSettingsincludes the necessaryResponseCachingproperty used in the policy logic.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Program.Middlewares.cs (2)
34-36: LGTM! Consistent refactoring pattern with API project.The replacement of explicit middleware configuration with shared extension methods matches the pattern used in the API project, promoting consistency and maintainability across the solution.
112-114: LGTM! Consistent Aspire support implementation.The conditional Aspire endpoint mapping follows the same pattern as the API project, ensuring consistent behavior across both server projects when Aspire features are enabled.
src/Templates/Boilerplate/Bit.Boilerplate/Boilerplate.slnx (3)
20-21: LGTM: Simplified folder declarationsRemoving explicit GUID Id attributes from folder elements simplifies the solution file structure while maintaining functionality.
Also applies to: 26-26, 30-30
38-38: LGTM: Added shared server project referenceThe addition of the shared server project reference supports code reuse and centralization of common server services.
39-41: LGTM: Conditional Aspire AppHost inclusionThe conditional inclusion of the Aspire AppHost project properly aligns with the aspire template parameter, ensuring the project is only included when Aspire support is enabled.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Program.Services.cs (3)
34-34: LGTM: Added shared services namespaceThe addition of the shared services namespace enables access to centralized service registration methods.
50-50: LGTM: Centralized shared services registrationCalling
AddServerSharedServices()early in the service registration process is the correct approach, allowing shared services to be available for subsequent registrations. This reduces code duplication and centralizes common infrastructure concerns.
376-377: LGTM: Enhanced AI services with OpenTelemetryThe addition of
.UseOpenTelemetry()to the AI service builder chains enhances observability for AI operations. This aligns well with the telemetry infrastructure provided by the shared services.Also applies to: 390-391, 402-403, 414-415
src/Templates/Boilerplate/Bit.Boilerplate/.template.config/template.json (4)
165-171: LGTM: Well-configured Aspire template parameterThe aspire boolean parameter is properly configured with a sensible default value of false and clear description. This allows users to opt-in to Aspire hosting features.
274-300: LGTM: Appropriate port generation for Aspire servicesThe three port generation symbols use a suitable range (2001-2300) for Aspire services, avoiding conflicts with common application ports. The generated ports will replace the placeholder values appropriately.
596-603: LGTM: Correct conditional exclusion of Aspire AppHostThe exclusion condition properly prevents the Aspire AppHost directory from being included when aspire is false, maintaining a clean template structure based on feature selection.
165-300: Ignore static analysis errors - JSON file is validThe static analysis errors from Biome are false positives. Biome is incorrectly attempting to parse this JSON configuration file as JavaScript/TypeScript. The JSON structure and syntax are completely valid.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.AppHost/Program.cs (5)
5-5: LGTM: Proper Aspire application builder initializationThe DistributedApplication builder is correctly initialized with command-line arguments, following Aspire hosting patterns.
7-27: Excellent database configuration with vector search supportThe database server configurations are well-implemented:
- Persistent container lifetimes ensure data survival across restarts
- Appropriate volume mappings for data persistence
- Vector search enabled images (SQL Server 2025, pgvector/pgvector) support modern AI workloads
- Proper conditional compilation for different database types
The choice of specific images with vector search capabilities aligns well with the AI features in the application.
29-41: LGTM: Comprehensive Azure Storage emulator setupThe Azure Blob Storage emulator configuration is thorough:
- Persistent lifetime with data volume ensures storage survival
- Standard port mappings (10000-10002) for blob, queue, and table services
- Proper service isolation with the
AddBlobsmethod
43-72: Well-architected project dependencies and resource managementThe project configuration demonstrates excellent Aspire patterns:
- Proper project references using the generated Projects namespace
- Correct dependency waiting with
.WaitFor()ensuring services start in order- Appropriate connection string mapping for different database types
- Clean separation between standalone and integrated API deployment modes
- Consistent resource reference patterns across different storage and database options
74-76: LGTM: Standard Aspire application lifecycleThe application build and run pattern follows standard Aspire hosting practices with proper async handling.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/WebApplicationExtensions.cs (3)
11-36: Excellent Aspire health check implementation with proper security considerationsThe
MapAspiremethod correctly implements Aspire health check endpoints:
- Properly restricts health check endpoints to development environments for security
- Implements both
/health(all checks) and/alive(live checks only) endpoints- Follows Aspire conventions with appropriate endpoint filtering
- Includes helpful documentation about security implications
The development-only restriction is crucial for production security.
38-58: Robust forwarded headers configuration with enhanced securityThe
UseAppForwardedHeadersmethod implements excellent security practices:
- Properly binds configuration to
ServerSharedSettingsfor centralized configuration- Merges
AllowedHostswith trusted origins from settings, preventing host spoofing- Conditionally applies forwarded headers only in development or when hosts are explicitly allowed
- Includes security warning about empty allowed hosts list
The host validation logic on line 48 effectively prevents attackers from spoofing links for password resets and other sensitive operations.
60-77: Well-integrated localization setup using shared culture managementThe
UseLocalizationmethod properly integrates with the existingCultureInfoManager:
- Correctly checks
InvariantGlobalizationflag to conditionally enable localization- Uses shared supported cultures and default culture for consistency
- Includes route data culture provider for URL-based culture selection
- Applies current culture to response headers for client-side detection
- Returns early when globalization is invariant, avoiding unnecessary configuration
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/HttpRequestExtensions.cs (2)
21-30: LGTM: Clean base URL construction.The
GetBaseUrlmethod properly usesUriBuilderand handles default port normalization correctly.
43-51: LGTM: Proper user agent header handling.The method correctly retrieves the user agent header, handles null/empty cases, and normalizes to lowercase.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Program.Services.cs (3)
34-34: LGTM: Proper integration of shared services.The call to
AddServerSharedServices()correctly integrates the shared server infrastructure within the conditional compilation block.
37-38: LGTM: Improved authentication scheme specification.Using the fully qualified
Microsoft.AspNetCore.Identity.IdentityConstants.BearerSchemeis more explicit and reduces ambiguity compared to string literals.
57-62: LGTM: Improved service registration organization.Moving the
ServerWebSettingssingleton registration after the API conditional block provides better logical organization and ensures it's available for all configuration paths.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/ServerApiSettings.cs (2)
7-7: LGTM: Proper using directive for shared dependency.Adding the using directive for
Boilerplate.Server.Sharedsupports the new inheritance hierarchy.
11-11: LGTM: Excellent architectural refactoring.Changing inheritance to
ServerSharedSettingsproperly centralizes shared configuration concerns while keeping API-specific settings in this class. This promotes code reuse and reduces duplication.src/Templates/Boilerplate/Bit.Boilerplate/src/Directory.Packages.props (2)
41-45: LGTM: Well-structured conditional Aspire package inclusions.The conditional package references based on MSBuild properties (
aspire,database,filesStorage) provide appropriate flexibility for different deployment scenarios.
46-52: Security and Compatibility Verification Completed
- OpenTelemetry.Exporter.OpenTelemetryProtocol v1.12.0 and Microsoft.Extensions.Http.Resilience v9.6.0 have no publicly disclosed CVEs or security advisories as of June 2025.
- No major compatibility issues have been reported for these versions (aside from non-security OTLP gRPC behavior on .NET 9).
- Continue to monitor upstream advisories and test against your target frameworks to ensure ongoing compatibility.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Extensions/HttpRequestExtensions.cs (4)
1-1: LGTM: Proper dependency update for shared project.Changing the using directive to
Boilerplate.Server.Sharedaligns with the architectural refactoring to centralize shared functionality.
5-5: LGTM: Appropriate class modifier change.Removing the
partialkeyword is correct since the shared extension methods were moved to the shared project, eliminating the need for partial classes.
7-10: LGTM: Improved method accessibility.Making the
IsFromCDNmethod public enhances its reusability across the codebase while maintaining its simple and correct implementation.
12-27: LGTM: Consistent settings dependency update.The change from
ServerApiSettingstoServerSharedSettingsis consistent with the inheritance refactoring and maintains the same functionality for origin validation.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Extensions/HttpRequestExtensions.cs (1)
15-15: Extension Method Accessibility VerifiedThe
GetLoweredUserAgentextension is publicly declared in the shared project and the Web project correctly references it. No further changes are needed.• In
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/HttpRequestExtensions.cs:public static string GetLoweredUserAgent(this HttpRequest request) { var userAgent = request.Headers[HeaderNames.UserAgent].ToString(); … }• In
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Boilerplate.Server.Web.csprojthere is a:<ProjectReference Include="..\Boilerplate.Server.Shared\Boilerplate.Server.Shared.csproj" />• The call in Web’s
HttpRequestExtensions.cs:var agent = request.GetLoweredUserAgent();will resolve correctly.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/ServerSharedSettings.cs (1)
47-50: Security consideration: Different trusted origin patterns between environments.The regex pattern in Development mode allows additional domains (
*.devtunnels.msand*.github.dev) that are not allowed in production. Ensure this is intentional and that these domains are only used for development purposes.The use of
GeneratedRegexattribute is excellent for performance as it pre-compiles the regex at build time.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Shared/Extensions/WebApplicationBuilderExtensions.cs (2)
54-55: Compression level set to Fastest - ensure this aligns with performance requirements.The compression providers are configured with
CompressionLevel.Fastest, which prioritizes speed over compression ratio. This is typically a good choice for web applications, but verify it aligns with your bandwidth vs. CPU trade-off requirements.
69-145: Well-structured Aspire service configuration.The Aspire service defaults implementation is comprehensive and follows best practices:
- Proper OpenTelemetry configuration for logging, metrics, and tracing
- Conditional OTLP exporter setup based on configuration
- Standard resilience and service discovery for HTTP clients
- Basic liveness health check
closes #11033
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Chores