Skip to content

Conversation

@ysmoradi
Copy link
Member

@ysmoradi ysmoradi commented Jun 30, 2025

closes #11033

Summary by CodeRabbit

  • New Features

    • Added optional Aspire distributed application hosting support, including new configuration options and project files.
    • Introduced a shared server project to centralize common services and settings.
    • Added extension methods for easier middleware and service configuration.
    • Enhanced logging and telemetry support with OpenTelemetry and related packages.
  • Bug Fixes

    • Simplified and unified middleware and service registration, reducing redundancy and potential misconfiguration.
  • Refactor

    • Moved and exposed several shared utility methods and settings for broader use.
    • Streamlined project structure and conditional feature inclusion based on configuration flags.
  • Chores

    • Updated documentation and configuration defaults for improved clarity and maintainability.

@ysmoradi ysmoradi requested review from Copilot and msynk June 30, 2025 19:56
@coderabbitai
Copy link

coderabbitai bot commented Jun 30, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This 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

File(s) / Group Change Summary
template.json, Boilerplate.Web.slnf, Boilerplate.slnx, Directory.Packages.props, appsettings.json Added "aspire" parameter, conditional project/package inclusion, and configuration logic for Aspire support.
Boilerplate.Server.AppHost/* (new files) Introduced new AppHost project for distributed app hosting with Aspire, including configs and entry point.
Boilerplate.Server.Shared/* (new files) Added shared server project with extensions for caching, localization, health, telemetry, and trusted origins.
Boilerplate.Server.Api/* Refactored to use shared services, removed/reorganized caching, compression, and trusted origin logic.
Boilerplate.Server.Web/* Refactored to use shared services, removed redundant service registrations, updated project references.
Extensions/* (Api, Web, Shared) Moved and reorganized extension methods for HttpContext/HttpRequest; centralized shared logic.
AppResponseCachePolicy.cs (Api, Shared) Moved caching policy class to shared project; updated constructor and namespace.
ServerApiSettings.cs, ServerWebSettings.cs Refactored settings classes to move shared logic to ServerSharedSettings; removed/relocated properties.
README.md, .template.config/template.json Minor doc and config updates, including anchor and whitespace fixes.

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
Loading

Assessment against linked issues

Objective (Issue #) Addressed Explanation
Add support for Aspire in bit Boilerplate project template (#11033)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Update README anchor (src/Websites/WikiDocs/README.md) Documentation anchor update is unrelated to Aspire support objective.

Poem

🐇
With Aspire now in every hop,
The boilerplate leaps to the top!
Shared code and hosts, all neat and bright,
Services bundled, templates light.
From configs deep to middlewares clear,
The rabbit cheers: "Aspire is here!"
🥕✨

✨ Finishing Touches
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Post Copyable Unit Tests in a Comment

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

Copilot AI left a 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 aspire template parameter and wire up MapAspire() and AddAspireServiceDefaults()
  • 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)

Copy link

@coderabbitai coderabbitai bot left a 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 .template extension 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.json only 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: Duplicate UserSecretsId across projects may leak secrets

UserSecretsId is 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

📥 Commits

Reviewing files that changed from the base of the PR and between d245ad0 and 00d6966.

📒 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 string

With && aspire == false gates, none of the RDBMS connection strings are emitted when the aspire flag is on.
Please confirm that:

  1. The Aspire host really injects an equivalent connection string into the API process at runtime (via secrets, environment variables, or d-apr config), and
  2. No library code tries to read Configuration["ConnectionStrings:SqlServerConnectionString"] when Aspire is enabled.

If either condition fails you’ll hit NullReference/InvalidOperationException on first DbContext construction.

src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Boilerplate.Server.Api.csproj (1)

87-88: 👍 Reference moved to the new shared project

The new relative path resolves correctly from Server.ApiServer.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 intentional

Removing the BCL defaults (System, System.Collections.Generic, …) forces every file to add explicit using directives, 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.Web now depends on Server.Shared, which in turn references some Web-specific middleware. Double-check that Server.Shared has 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

  1. Ports 2030-2032 are hard-coded. If multiple Aspire hosts are run in parallel (common in integration-test pipelines) they will collide. Consider 0 (dynamic) or template symbols.
  2. Variable names match preview Aspire docs, but note that the final spec renamed
    DOTNET_DASHBOARD_OTLP_ENDPOINT_URLDOTNET_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() and UseLocalization() 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 internal to public is 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.Services to Boilerplate.Server.Shared.Services correctly reflects the migration to the shared project.


12-12: LGTM! Constructor parameter update supports shared configuration.

The change from ServerWebSettings to ServerSharedSettings aligns with the centralization of shared configuration. Based on the relevant code snippet, ServerSharedSettings includes the necessary ResponseCaching property 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 declarations

Removing 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 reference

The addition of the shared server project reference supports code reuse and centralization of common server services.


39-41: LGTM: Conditional Aspire AppHost inclusion

The 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 namespace

The addition of the shared services namespace enables access to centralized service registration methods.


50-50: LGTM: Centralized shared services registration

Calling 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 OpenTelemetry

The 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 parameter

The 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 services

The 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 AppHost

The 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 valid

The 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 initialization

The DistributedApplication builder is correctly initialized with command-line arguments, following Aspire hosting patterns.


7-27: Excellent database configuration with vector search support

The 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 setup

The 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 AddBlobs method

43-72: Well-architected project dependencies and resource management

The 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 lifecycle

The 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 considerations

The MapAspire method 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 security

The UseAppForwardedHeaders method implements excellent security practices:

  • Properly binds configuration to ServerSharedSettings for centralized configuration
  • Merges AllowedHosts with 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 management

The UseLocalization method properly integrates with the existing CultureInfoManager:

  • Correctly checks InvariantGlobalization flag 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 GetBaseUrl method properly uses UriBuilder and 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.BearerScheme is more explicit and reduces ambiguity compared to string literals.


57-62: LGTM: Improved service registration organization.

Moving the ServerWebSettings singleton 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.Shared supports the new inheritance hierarchy.


11-11: LGTM: Excellent architectural refactoring.

Changing inheritance to ServerSharedSettings properly 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.Shared aligns with the architectural refactoring to centralize shared functionality.


5-5: LGTM: Appropriate class modifier change.

Removing the partial keyword 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 IsFromCDN method public enhances its reusability across the codebase while maintaining its simple and correct implementation.


12-27: LGTM: Consistent settings dependency update.

The change from ServerApiSettings to ServerSharedSettings is 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 Verified

The GetLoweredUserAgent extension 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.csproj there 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.ms and *.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 GeneratedRegex attribute 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

@ysmoradi ysmoradi merged commit 934afc7 into bitfoundation:develop Jul 2, 2025
3 checks passed
@ysmoradi ysmoradi deleted the 11033 branch July 2, 2025 07:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for aspire in bit Boilerplate project template is missing

1 participant