-
Notifications
You must be signed in to change notification settings - Fork 0
Upgrade to .NET 10 and update dependencies #42
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
Migrated all projects to target .NET 10.0, updated NuGet package versions across the solution, and replaced the legacy .sln file with a new .slnx format. CI/CD workflows and documentation were updated to reflect .NET 10.0 usage. Improved Swagger versioning configuration and fixed minor issues in Redis cache and AutoMapper registration.
Reviewer's Guide.NET SDK and solution upgraded to .NET 10, CI workflows and docs updated accordingly, Swagger versioning moved to ConfigureOptions, Redis cache and AutoMapper registrations adjusted for newer APIs, and the legacy .sln was replaced with a .slnx solution file. Sequence diagram for Swagger configuration using ConfigureOptionssequenceDiagram
participant AppStartup
participant ServiceCollection
participant ApiVersioningExtension as AetherApiVersioningServiceCollectionExtensions
participant ConfigureSwaggerOptionsFactory
participant ConfigureSwaggerOptions
participant ApiVersionDescriptionProvider as IApiVersionDescriptionProvider
participant SwaggerGenOptions
AppStartup->>ApiVersioningExtension: AddAetherApiVersioning(services, apiTitle)
ApiVersioningExtension->>ServiceCollection: AddSwaggerGen()
ApiVersioningExtension->>ServiceCollection: AddTransient(IConfigureOptions_SwaggerGenOptions_)
ServiceCollection-->>ConfigureSwaggerOptionsFactory: resolve IConfigureOptions_SwaggerGenOptions_
ConfigureSwaggerOptionsFactory->>ApiVersionDescriptionProvider: GetRequiredService()
ConfigureSwaggerOptionsFactory-->>ServiceCollection: new ConfigureSwaggerOptions(provider, apiTitle)
AppStartup->>SwaggerGenOptions: instantiate options
AppStartup->>ConfigureSwaggerOptions: Configure(options)
ConfigureSwaggerOptions->>ApiVersionDescriptionProvider: ApiVersionDescriptions
loop for each ApiVersionDescription
ConfigureSwaggerOptions->>SwaggerGenOptions: SwaggerDoc(groupName, OpenApiInfo)
end
Sequence diagram for updated Redis cache get and set operationssequenceDiagram
participant Caller
participant RedisCache as RedisDistributedCacheService
participant Database as IDatabase
participant Logger as ILogger
Caller->>RedisCache: GetAsync<T>(key)
RedisCache->>Database: StringGetAsync(key)
Database-->>RedisCache: RedisValue cachedValue
alt cachedValue.HasValue is false
RedisCache-->>Caller: null
else cachedValue.HasValue is true
RedisCache->>RedisCache: JsonSerializer.Deserialize<T>((string)cachedValue)
RedisCache->>Logger: LogDebug("Cache hit for key", key)
RedisCache-->>Caller: T result
end
Caller->>RedisCache: SetAsync<T>(key, value, options)
RedisCache->>RedisCache: JsonSerializer.Serialize(value)
RedisCache->>RedisCache: determine expiry from options
RedisCache->>Database: StringSetAsync(key, serializedValue, Expiration.KeepTtl)
Database-->>RedisCache: bool success
RedisCache->>Logger: LogDebug("Successfully cached value for key", key)
RedisCache-->>Caller: Task completed
Class diagram for updated Swagger versioning and DI configurationclassDiagram
class AetherApiVersioningServiceCollectionExtensions {
+IServiceCollection AddAetherApiVersioning(IServiceCollection services, string apiTitle)
}
class ConfigureSwaggerOptions {
-IApiVersionDescriptionProvider _provider
-string _apiTitle
+ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider, string apiTitle)
+void Configure(SwaggerGenOptions options)
}
class IApiVersionDescriptionProvider {
<<interface>>
+IReadOnlyList<ApiVersionDescription> ApiVersionDescriptions
}
class ApiVersionDescription {
+string GroupName
+ApiVersion ApiVersion
+bool IsDeprecated
}
class SwaggerGenOptions {
+void SwaggerDoc(string name, OpenApiInfo info)
}
class OpenApiInfo {
+string Title
+string Version
+string Description
}
class IServiceCollection {
<<interface>>
+IServiceCollection AddSwaggerGen()
+IServiceCollection AddTransient(TService implementationFactory)
}
class IConfigureOptions_SwaggerGenOptions_ {
<<interface>>
+void Configure(SwaggerGenOptions options)
}
AetherApiVersioningServiceCollectionExtensions ..> IServiceCollection : extends
AetherApiVersioningServiceCollectionExtensions ..> ConfigureSwaggerOptions : registers
ConfigureSwaggerOptions ..|> IConfigureOptions_SwaggerGenOptions_
ConfigureSwaggerOptions --> IApiVersionDescriptionProvider : uses
ConfigureSwaggerOptions --> SwaggerGenOptions : configures
SwaggerGenOptions --> OpenApiInfo : creates
IApiVersionDescriptionProvider --> ApiVersionDescription : provides
Class diagram for updated caching and AutoMapper registrationclassDiagram
class CachedServiceProviderBase {
+ConcurrentDictionary~ServiceIdentifier, Lazy~object~~ CachedServices
+IServiceProvider ServiceProvider
+object GetService(Type serviceType, Func~IServiceProvider, object~ factory, object serviceKey)
+object GetRequiredKeyedService(Type serviceType, object serviceKey)
}
class IKeyedServiceProvider {
<<interface>>
+object GetKeyedService(Type serviceType, object serviceKey)
+object GetRequiredKeyedService(Type serviceType, object serviceKey)
}
CachedServiceProviderBase --> IKeyedServiceProvider : casts_to
class RedisDistributedCacheService {
-IDatabase database
-ILogger logger
-JsonSerializerOptions jsonOptions
+Task~T~ GetAsync~T~(string key)
+Task SetAsync~T~(string key, T value, DistributedCacheEntryOptions options)
}
class IDatabase {
<<interface>>
+Task~RedisValue~ StringGetAsync(string key)
+Task bool StringSetAsync(string key, string value, TimeSpan expiry)
+Task bool StringSetAsync(string key, string value, Expiration expiry)
}
class RedisValue {
+bool HasValue
}
class Expiration {
<<enum>>
KeepTtl
}
class JsonSerializerOptions
class ILogger {
<<interface>>
+void LogDebug(string message, object arg1)
+void LogError(Exception exception, string message, object arg1)
}
class DistributedCacheEntryOptions {
+TimeSpan? AbsoluteExpirationRelativeToNow
+TimeSpan? SlidingExpiration
}
RedisDistributedCacheService --> IDatabase : uses
RedisDistributedCacheService --> ILogger : logs_with
RedisDistributedCacheService --> JsonSerializerOptions : uses
RedisDistributedCacheService --> DistributedCacheEntryOptions : reads
IDatabase --> RedisValue : returns
RedisDistributedCacheService --> Expiration : uses_KeepTtl
class AetherMapperServiceCollectionExtensions {
+IServiceCollection AddAetherAutoMapperMapper(IServiceCollection services, List~Type~ autoMapperTypes)
}
class IObjectMapper {
<<interface>>
}
class AutoMapperAdapter {
+AutoMapperAdapter(IMapper mapper)
}
class IObjectMapper_TSource_TDestination_ {
<<interface>>
}
class AutoMapperAdapter_TSource_TDestination_ {
}
class IMapper {
<<interface>>
}
AetherMapperServiceCollectionExtensions ..> IServiceCollection : extends
AetherMapperServiceCollectionExtensions ..> IObjectMapper : registers
AetherMapperServiceCollectionExtensions ..> AutoMapperAdapter : registers
AetherMapperServiceCollectionExtensions ..> IObjectMapper_TSource_TDestination_ : registers
AetherMapperServiceCollectionExtensions ..> AutoMapperAdapter_TSource_TDestination_ : registers
AutoMapperAdapter --> IMapper
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Note
|
| Cohort / File(s) | Summary |
|---|---|
Build Infrastructure & SDK global.json, .github/workflows/check-sonar.yml, .github/workflows/publish-nuget.yml, README.md |
Bump SDK to 10.0.102; CI workflows and README badge updated to build framework/BBT.Aether.slnx and target .NET 10.0 |
Solution Files framework/BBT.Aether.sln, framework/BBT.Aether.slnx |
Removed legacy .sln; added .slnx referencing ten projects under /src/ |
Package Management Directory.Packages.props |
Large dependency upgrades (ASP.NET Core, EF Core, OpenTelemetry, Dapr, PostSharp, Swashbuckle, AutoMapper, StackExchange.Redis, etc.) and new/updated package versions aligned to .NET 10 ecosystem |
Project Target Frameworks framework/src/.../*.csproj |
All framework projects updated from net9.0 → net10.0; BBT.Aether.AspNetCore.csproj also adjusted package references (added Microsoft.OpenApi) and reorganized project refs |
Compiler Warnings common.props |
Added DAPR_JOBS and DAPR_DISTRIBUTEDLOCK to <NoWarn> list |
Swagger / API Versioning framework/src/BBT.Aether.AspNetCore/Microsoft/Extensions/DependencyInjection/AetherApiVersioningServiceCollectionExtensions.cs |
Replaced inline Swagger per-version loop with IConfigureOptions<SwaggerGenOptions> (ConfigureSwaggerOptions) and registered AddSwaggerGen plus the configure-options service |
Service Provider / DI framework/src/BBT.Aether.Core/BBT/Aether/DependencyInjection/CachedServiceProviderBase.cs |
Keyed service resolution now casts ServiceProvider to IKeyedServiceProvider before calling keyed retrieval methods |
AutoMapper Registration framework/src/BBT.Aether.Infrastructure/Microsoft/Extensions/DependencyInjection/AetherMapperServiceCollectionExtensions.cs |
AddAutoMapper now called using overload with an explicit (empty) configuration delegate |
Redis Distributed Cache framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedCache/Redis/RedisDistributedCacheService.cs |
GetAsync casts cached value to string before deserialization; SetAsync uses keepTtl: false explicitly when setting string value |
Test & Misc Projects framework/src/BBT.Aether.TestBase/*.csproj, other small csproj files |
TargetFramework bumps and minor project-file formatting changes |
Sequence Diagram(s)
sequenceDiagram
participant Startup as Startup / Composition Root
participant Services as IServiceCollection
participant SwaggerGen as SwaggerGen (Swashbuckle)
participant Provider as IApiVersionDescriptionProvider
participant Configure as ConfigureSwaggerOptions
Startup->>Services: Call AddSwaggerGen()
Startup->>Services: Register IConfigureOptions<SwaggerGenOptions> (ConfigureSwaggerOptions)
Services->>SwaggerGen: Register Swagger generator
Services->>Provider: Resolve API version descriptions at runtime
Services->>Configure: Instantiate ConfigureSwaggerOptions(provider, apiTitle)
Configure->>Provider: Query ApiVersionDescriptions
Configure->>SwaggerGen: Configure per-version SwaggerDoc entries
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~25 minutes
Suggested labels
enhancement
Suggested reviewers
- mokoker
- middt
Poem
🐰 Hopping through frameworks with glee,
From nine to ten, wild and free!
Solutions swapped to.slnxdelight,
Swagger hums and Redis keeps TTLs right,
Dependencies prance in shimmering light ✨
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |
✅ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The pull request title 'Upgrade to .NET 10 and update dependencies' accurately and concisely describes the primary changes in the changeset. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing touches
- 📝 Generate docstrings
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
- Commit unit tests in branch
41-upgrade-to-net-10-lts
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
Summary of ChangesHello @yilmaztayfun, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly updates the project's foundational technologies by migrating the entire solution to .NET 10.0 and refreshing a wide array of NuGet package dependencies. Beyond the core framework upgrade, it modernizes the solution file format, refines the API documentation setup for better versioning, and includes targeted fixes for caching and object mapping, all aimed at improving the stability, performance, and maintainability of the codebase. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
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.
Hey - I've found 1 issue, and left some high level feedback:
- In
RedisDistributedCacheService.SetAsync, you now compute anexpiryvalue but passExpiration.KeepTtltoStringSetAsync, so the logged expiry no longer matches the actual behavior; if the intent is to honor absolute/sliding expirations, pass anExpirationbased onexpiryinstead ofKeepTtl. - In
AddAetherApiVersioning, consider registeringConfigureSwaggerOptionsviaservices.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();and letting DI supply dependencies (ensuringIApiVersionDescriptionProvideris registered elsewhere) rather than constructingConfigureSwaggerOptionsmanually in a factory.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `RedisDistributedCacheService.SetAsync`, you now compute an `expiry` value but pass `Expiration.KeepTtl` to `StringSetAsync`, so the logged expiry no longer matches the actual behavior; if the intent is to honor absolute/sliding expirations, pass an `Expiration` based on `expiry` instead of `KeepTtl`.
- In `AddAetherApiVersioning`, consider registering `ConfigureSwaggerOptions` via `services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();` and letting DI supply dependencies (ensuring `IApiVersionDescriptionProvider` is registered elsewhere) rather than constructing `ConfigureSwaggerOptions` manually in a factory.
## Individual Comments
### Comment 1
<location> `framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedCache/Redis/RedisDistributedCacheService.cs:69` </location>
<code_context>
expiry = options.SlidingExpiration.Value;
}
- await database.StringSetAsync(key, serializedValue, expiry);
+ await database.StringSetAsync(key, serializedValue, Expiration.KeepTtl);
_logger.LogDebug("Successfully cached value for key: {Key} with expiry: {Expiry}", key, expiry);
}
</code_context>
<issue_to_address>
**issue (bug_risk):** The change to Expiration.KeepTtl ignores the computed expiry and may not match the IDatabase API.
This change stops applying the computed `expiry` while the log still reports it, which is misleading. It also likely breaks the expected `IDatabase.StringSetAsync` usage, since that overload normally takes a `TimeSpan?` and `Expiration.KeepTtl` may resolve to a different overload or not compile. Please either keep using the explicit `expiry` (and log it) or add a separate path for the TTL-preserving case with matching logging.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
.../BBT.Aether.Infrastructure/BBT/Aether/DistributedCache/Redis/RedisDistributedCacheService.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.
Code Review
This pull request successfully upgrades the project to .NET 10, updates a wide range of dependencies, and modernizes the solution structure by adopting the .slnx format. The code refactoring, particularly for Swagger versioning configuration and keyed service resolution, introduces significant improvements by adhering to best practices. However, I have found a critical issue in the Redis cache implementation that breaks the cache expiration logic and needs to be addressed.
| } | ||
|
|
||
| await database.StringSetAsync(key, serializedValue, expiry); | ||
| await database.StringSetAsync(key, serializedValue, Expiration.KeepTtl); |
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.
This change introduces a critical issue in cache expiration handling. The Expiration.KeepTtl construct is not valid and will likely cause a compilation error. Even if the intent was to use an option to preserve TTL (like keepTtl: true), it would be incorrect in this context as it would ignore the expiry calculated from DistributedCacheEntryOptions, thus violating the expected behavior of SetAsync.
The expiry variable is calculated but no longer used, which confirms the logic is broken. To ensure cache items are set with the correct expiration as defined by the options, the original implementation should be restored.
await database.StringSetAsync(key, serializedValue, expiry);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: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedCache/Redis/RedisDistributedCacheService.cs (1)
58-70: Critical bug: Computed expiry is never applied.The
expiryvalue is computed fromoptions(lines 60-67) but completely ignored.Expiration.KeepTtlpreserves the existing TTL on the key rather than applying the new expiration. This means:
- New keys will have no expiration (infinite TTL)
- Existing keys will retain their old TTL, ignoring caller-specified options
- The log message on line 70 is misleading—it reports an expiry that was never applied
This breaks cache expiration functionality entirely, leading to stale data and potential memory growth.
🐛 Proposed fix
- await database.StringSetAsync(key, serializedValue, Expiration.KeepTtl); + await database.StringSetAsync(key, serializedValue, expiry);framework/src/BBT.Aether.Core/BBT/Aether/DependencyInjection/CachedServiceProviderBase.cs (1)
50-64: Replace unsafe cast with safe pattern to align with interface contract and provide better error messages.The direct cast
(IKeyedServiceProvider)ServiceProviderviolates the class's interface contract.CachedServiceProviderBaseimplementsICachedServiceProviderBase : IKeyedServiceProvider, which commits to supporting keyed services, but the property accepts anyIServiceProvider. If a provider that doesn't implementIKeyedServiceProvideris passed, the cast throwsInvalidCastExceptionwith no context.The codebase already provides a safe pattern in
ServiceProviderKeyedServiceExtensionsusingischecks and descriptiveInvalidOperationExceptionmessages. Use the same defensive approach here:Suggested fix
public object? GetKeyedService(Type serviceType, object? serviceKey) { return CachedServices.GetOrAdd( new ServiceIdentifier(serviceKey, serviceType), - _ => new Lazy<object?>(() => ((IKeyedServiceProvider)ServiceProvider).GetKeyedService(serviceType, serviceKey)) + _ => new Lazy<object?>(() => + { + if (ServiceProvider is IKeyedServiceProvider keyedServiceProvider) + { + return keyedServiceProvider.GetKeyedService(serviceType, serviceKey); + } + throw new InvalidOperationException("This service provider doesn't support keyed services."); + }) ).Value; } public object GetRequiredKeyedService(Type serviceType, object? serviceKey) { return CachedServices.GetOrAdd( new ServiceIdentifier(serviceKey, serviceType), - _ => new Lazy<object?>(() => ((IKeyedServiceProvider)ServiceProvider).GetRequiredKeyedService(serviceType, serviceKey)) + _ => new Lazy<object?>(() => + { + if (ServiceProvider is IKeyedServiceProvider keyedServiceProvider) + { + return keyedServiceProvider.GetRequiredKeyedService(serviceType, serviceKey); + } + throw new InvalidOperationException("This service provider doesn't support keyed services."); + }) ).Value!; }Alternatively, change the constructor parameter and property type to
IKeyedServiceProviderto make the requirement explicit at compile time..github/workflows/check-sonar.yml (1)
39-46: Missing .NET 10.0 SDK setup step.This workflow builds a .NET 10 solution but doesn't include a
setup-dotnetaction to ensure the .NET 10.0 SDK is available. Thewindows-latestrunner may not have .NET 10.0 pre-installed, which could cause build failures.🔧 Proposed fix: Add .NET SDK setup step
- name: Install SonarQube Cloud scanner if: steps.cache-sonar-scanner.outputs.cache-hit != 'true' shell: powershell run: | New-Item -Path .\.sonar\scanner -ItemType Directory dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x - name: Build and analyzeframework/src/BBT.Aether.AspNetCore/BBT.Aether.AspNetCore.csproj (1)
18-41: Align OpenTelemetry instrumentation package versions.The OpenTelemetry.Instrumentation.EntityFrameworkCore and OpenTelemetry.Instrumentation.Process packages are pinned to 1.11.0-beta.1 while other OpenTelemetry packages use 1.14.0. Update these to 1.14.0 for consistency, or document why the beta versions are required. The Microsoft.OpenApi + Microsoft.AspNetCore.OpenApi combination is standard and appropriate. All project references (Abstractions, Application, Core) are actively used and necessary.
🤖 Fix all issues with AI agents
In `@Directory.Packages.props`:
- Line 122: Update the Oracle.EntityFrameworkCore package version in the
Directory.Packages.props entry for PackageVersion
Include="Oracle.EntityFrameworkCore" from 9.23.60 to 10.23.26000 so the Oracle
provider targets EF Core 10 and aligns with Microsoft.EntityFrameworkCore
10.0.2; ensure the Version attribute value is changed to "10.23.26000" and save
the props file.
- Line 150: Update the Serilog.Extensions.Logging package version from 10.0.2 to
the existing NuGet version 10.0.0 in the central package management entry (the
PackageVersion element with Include="Serilog.Extensions.Logging"); modify the
Version attribute to "10.0.0" so package restore succeeds and check for any
other occurrences of Serilog.Extensions.Logging version strings to keep them
consistent.
- Line 51: Update the ResponseCompression package declaration to match the other
ASP.NET packages by changing the PackageVersion entry for
Microsoft.AspNetCore.ResponseCompression from 2.3.9 to 10.0.2; locate the XML
element with Include="Microsoft.AspNetCore.ResponseCompression" in the
centralized package props and bump its Version attribute to 10.0.2 so the
runtime and the custom configuration used in
AetherAspNetCoreModuleServiceCollectionExtensions and
AetherApplicationBuilderExtensions align with the .NET 10 dependency set.
- Around line 192-194: The package versions are inconsistent: update
OpenTelemetry.Instrumentation.EntityFrameworkCore and
OpenTelemetry.Instrumentation.Process from 1.11.0-beta.1 to the newer
1.14.0-beta.2, and bump Npgsql.OpenTelemetry from 8.0.6 to a 10.x release (e.g.,
10.0.x) so it aligns with Npgsql.EntityFrameworkCore.PostgreSQL 10.0.2; modify
the PackageVersion entries for
OpenTelemetry.Instrumentation.EntityFrameworkCore,
OpenTelemetry.Instrumentation.Process, and Npgsql.OpenTelemetry to the indicated
newer versions to ensure compatibility.
🧹 Nitpick comments (5)
framework/src/BBT.Aether.Domain/BBT.Aether.Domain.csproj (1)
11-11: Consider removing legacyAssetTargetFallback.The
portable-net45+win8+wp8+wpa81fallback targets are obsolete portable class library profiles. For a .NET 10 project, these are unlikely to be needed unless consuming very old NuGet packages.framework/src/BBT.Aether.Infrastructure/Microsoft/Extensions/DependencyInjection/AetherMapperServiceCollectionExtensions.cs (1)
15-19: The empty configuration delegate is required by AutoMapper 16's API.In AutoMapper 16, all
AddAutoMapperoverloads require anAction<IMapperConfigurationExpression>as the first parameter. The empty lambda (_ => {}) is mandatory, not unnecessary. If you prefer a more compact style, you can safely inline it to a single line for readability, but this is a stylistic choice only.framework/src/BBT.Aether.TestBase/BBT.Aether.TestBase.csproj (1)
11-11: Consider removing legacyAssetTargetFallback.The
portable-net45+win8+wp8+wpa81fallback targets legacy platforms that are unlikely to be relevant for a .NET 10 test base project. Consider removing this if there are no specific package compatibility requirements.framework/src/BBT.Aether.Core/BBT.Aether.Core.csproj (1)
37-45: Consider removing dead.NETStandardconditionals.These
ItemGroupblocks are conditioned onTargetFrameworkIdentifier == '.NETStandard', but the project now exclusively targetsnet10.0. These conditions will never evaluate to true and can be removed to reduce clutter.🧹 Suggested cleanup
- <ItemGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETStandard' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '2.1')) "> - <PackageReference Include="System.ComponentModel.Annotations" /> - </ItemGroup> - <ItemGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETStandard' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '2.0')) "> - <PackageReference Include="Nullable"> - <PrivateAssets>all</PrivateAssets> - <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> - </PackageReference> - </ItemGroup>Directory.Packages.props (1)
172-172: System.Text.Json version is inconsistent with other System. packages.*
System.Text.Jsonis at8.0.5while related packages have been updated to10.0.2:
- System.Collections.Immutable
- System.Security.Permissions
- System.Text.Encoding.CodePages
- System.Text.Encodings.Web
System.Text.Json 10.0.2 is available as a stable release. Update to
10.0.2for consistency with the .NET 10 upgrade, unless there's a specific compatibility reason to remain on 8.0.5.
| <PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.0" /> | ||
| <PackageVersion Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="9.0.0" /> | ||
| <PackageVersion Include="Microsoft.AspNetCore.Diagnostics.Middleware" Version="8.10.0" /> | ||
| <PackageVersion Include="Microsoft.AspNetCore.ResponseCompression" Version="2.3.9" /> |
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for ResponseCompression usage in the codebase
rg -n 'ResponseCompression|UseResponseCompression|AddResponseCompression' --type=csRepository: burgan-tech/aether
Length of output: 2707
🏁 Script executed:
#!/bin/bash
# Check the Directory.Packages.props file to see all package versions
head -60 Directory.Packages.props | tail -20Repository: burgan-tech/aether
Length of output: 1659
🏁 Script executed:
#!/bin/bash
# Get full context of packages around ResponseCompression
grep -n "Microsoft.AspNetCore" Directory.Packages.props | head -20Repository: burgan-tech/aether
Length of output: 1977
Update Microsoft.AspNetCore.ResponseCompression to version 10.0.2.
This package is at 2.3.9 (from .NET Core 2.x era) while other Microsoft.AspNetCore.* packages are at 10.0.2. The code actively uses ResponseCompression with custom configuration in AetherAspNetCoreModuleServiceCollectionExtensions.cs and AetherApplicationBuilderExtensions.cs, so the package cannot be removed. The version mismatch creates a compatibility problem with the .NET 10 target and should be updated to align with other dependencies.
🤖 Prompt for AI Agents
In `@Directory.Packages.props` at line 51, Update the ResponseCompression package
declaration to match the other ASP.NET packages by changing the PackageVersion
entry for Microsoft.AspNetCore.ResponseCompression from 2.3.9 to 10.0.2; locate
the XML element with Include="Microsoft.AspNetCore.ResponseCompression" in the
centralized package props and bump its Version attribute to 10.0.2 so the
runtime and the custom configuration used in
AetherAspNetCoreModuleServiceCollectionExtensions and
AetherApplicationBuilderExtensions align with the .NET 10 dependency set.
| @@ -121,7 +122,7 @@ | |||
| <PackageVersion Include="Oracle.EntityFrameworkCore" Version="9.23.60" /> | |||
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Fetch the complete list of Oracle.EntityFrameworkCore versions from NuGet
curl -s "https://api.nuget.org/v3-flatcontainer/oracle.entityframeworkcore/index.json" | jq -r '.versions | reverse | .[:20]'Repository: burgan-tech/aether
Length of output: 342
Update Oracle.EntityFrameworkCore to 10.23.26000 for EF Core 10 compatibility.
Oracle.EntityFrameworkCore is currently at 9.23.60, which targets EF Core 9. Version 10.23.26000 is available and supports EF Core 10, matching the Microsoft.EntityFrameworkCore packages at 10.0.2.
🤖 Prompt for AI Agents
In `@Directory.Packages.props` at line 122, Update the Oracle.EntityFrameworkCore
package version in the Directory.Packages.props entry for PackageVersion
Include="Oracle.EntityFrameworkCore" from 9.23.60 to 10.23.26000 so the Oracle
provider targets EF Core 10 and aligns with Microsoft.EntityFrameworkCore
10.0.2; ensure the Version attribute value is changed to "10.23.26000" and save
the props file.
| <PackageVersion Include="Serilog.Enrichers.Sensitive" Version="1.7.3" /> | ||
| <PackageVersion Include="Serilog.Formatting.Compact" Version="3.0.0" /> | ||
| <PackageVersion Include="Serilog.Extensions.Logging" Version="9.0.0" /> | ||
| <PackageVersion Include="Serilog.Extensions.Logging" Version="10.0.2" /> |
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check available versions for Serilog.Extensions.Logging on NuGet
curl -s "https://api.nuget.org/v3-flatcontainer/serilog.extensions.logging/index.json" | jq '.versions'Repository: burgan-tech/aether
Length of output: 2204
Use version 10.0.0 for Serilog.Extensions.Logging.
Version 10.0.2 does not exist on NuGet. The latest available version is 10.0.0. The package restore will fail with the specified version.
🤖 Prompt for AI Agents
In `@Directory.Packages.props` at line 150, Update the Serilog.Extensions.Logging
package version from 10.0.2 to the existing NuGet version 10.0.0 in the central
package management entry (the PackageVersion element with
Include="Serilog.Extensions.Logging"); modify the Version attribute to "10.0.0"
so package restore succeeds and check for any other occurrences of
Serilog.Extensions.Logging version strings to keep them consistent.
| <PackageVersion Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.11.0-beta.1" /> | ||
| <PackageVersion Include="OpenTelemetry.Instrumentation.Process" Version="1.11.0-beta.1" /> | ||
| <PackageVersion Include="Npgsql.OpenTelemetry" Version="8.0.6" /> |
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.
🧩 Analysis chain
🏁 Script executed:
# First, let's look at the full context of the Directory.Packages.props file
# around lines 183-194
sed -n '180,200p' Directory.Packages.propsRepository: burgan-tech/aether
Length of output: 1666
🏁 Script executed:
# Also search for OpenTelemetry core packages to check their versions
rg "OpenTelemetry.*Version=" Directory.Packages.props | head -20Repository: burgan-tech/aether
Length of output: 1145
🏁 Script executed:
# Query NuGet API for latest available versions
# OpenTelemetry.Instrumentation.EntityFrameworkCore
curl -s "https://api.nuget.org/v3-flatcontainer/opentelemetry.instrumentation.entityframeworkcore/index.json" | jq '.versions | sort_by(split(".") | map(tonumber)) | reverse | .[0:10]'Repository: burgan-tech/aether
Length of output: 164
🏁 Script executed:
# Query for Npgsql.OpenTelemetry latest versions
curl -s "https://api.nuget.org/v3-flatcontainer/npgsql.opentelemetry/index.json" | jq '.versions | sort_by(split(".") | map(tonumber)) | reverse | .[0:10]'Repository: burgan-tech/aether
Length of output: 162
🏁 Script executed:
# Query for OpenTelemetry.Instrumentation.Process latest versions
curl -s "https://api.nuget.org/v3-flatcontainer/opentelemetry.instrumentation.process/index.json" | jq '.versions | sort_by(split(".") | map(tonumber)) | reverse | .[0:10]'Repository: burgan-tech/aether
Length of output: 165
🏁 Script executed:
# Query latest versions more directly
python3 <<'EOF'
import json
import urllib.request
packages = [
"opentelemetry.instrumentation.entityframeworkcore",
"opentelemetry.instrumentation.process",
"npgsql.opentelemetry"
]
for pkg in packages:
url = f"https://api.nuget.org/v3-flatcontainer/{pkg}/index.json"
try:
with urllib.request.urlopen(url, timeout=5) as response:
data = json.loads(response.read().decode())
versions = data.get('versions', [])
print(f"\n{pkg}:")
print(f" Total versions: {len(versions)}")
print(f" Latest 5: {versions[-5:]}")
except Exception as e:
print(f"Error for {pkg}: {e}")
EOFRepository: burgan-tech/aether
Length of output: 605
🏁 Script executed:
# Also check for Npgsql version in the file
rg "Npgsql" Directory.Packages.props | grep -E "(Version|Include)"Repository: burgan-tech/aether
Length of output: 219
🌐 Web query:
OpenTelemetry.Instrumentation.EntityFrameworkCore latest stable version NuGet
💡 Result:
There is no stable (non‑prerelease) NuGet release. The latest published version is 1.14.0‑beta.2 (prerelease) — last updated November 14, 2025. [1]
[1] NuGet: OpenTelemetry.Instrumentation.EntityFrameworkCore (version list).
🌐 Web query:
OpenTelemetry.Instrumentation.Process latest stable version NuGet 2025
💡 Result:
There is no stable (non‑prerelease) NuGet release of OpenTelemetry.Instrumentation.Process in 2025. The latest published version is 1.14.0-beta.2 (prerelease), published 2025-11-14. [1]
Sources:
- NuGet package page for OpenTelemetry.Instrumentation.Process (shows 1.14.0-beta.2 as latest). [1]
🌐 Web query:
Npgsql.OpenTelemetry 8.0.6 compatibility Npgsql 10.0
💡 Result:
Short answer: Yes—technically Npgsql.OpenTelemetry 8.0.6 can be used with Npgsql 10.0 (the Npgsql.OpenTelemetry 8.0.6 NuGet package lists Npgsql (>= 8.0.6) as a dependency, so Npgsql 10 satisfies that). [1][2]
Caveat: Npgsql 10.0 changed tracing/metrics to align with OpenTelemetry semantic conventions and renamed metrics/spans in a breaking way, so behavior (metric names, span tags) may differ from what Npgsql.OpenTelemetry 8.x expects. For best results use an OpenTelemetry package version that targets Npgsql 10 or upgrade to the matching Npgsql.OpenTelemetry 10.x release. [3][2]
Sources:
- Npgsql.OpenTelemetry 8.0.6 NuGet (dependencies). [1]
- Npgsql 10.0 release notes (tracing/metrics breaking changes). [2]
- Npgsql diagnostics / metrics docs (notes on metric name changes). [3]
Update OpenTelemetry instrumentation packages and Npgsql.OpenTelemetry version mismatch.
OpenTelemetry.Instrumentation.EntityFrameworkCore and OpenTelemetry.Instrumentation.Process are on 1.11.0-beta.1, while the latest available (also beta) is 1.14.0-beta.2. No stable versions of these packages exist yet.
More importantly, Npgsql.OpenTelemetry at 8.0.6 is mismatched with Npgsql.EntityFrameworkCore.PostgreSQL at 10.0.2. Npgsql 10.0 introduced breaking changes to tracing and metrics. For compatibility, upgrade to Npgsql.OpenTelemetry 10.x to align with Npgsql 10.0.
🤖 Prompt for AI Agents
In `@Directory.Packages.props` around lines 192 - 194, The package versions are
inconsistent: update OpenTelemetry.Instrumentation.EntityFrameworkCore and
OpenTelemetry.Instrumentation.Process from 1.11.0-beta.1 to the newer
1.14.0-beta.2, and bump Npgsql.OpenTelemetry from 8.0.6 to a 10.x release (e.g.,
10.0.x) so it aligns with Npgsql.EntityFrameworkCore.PostgreSQL 10.0.2; modify
the PackageVersion entries for
OpenTelemetry.Instrumentation.EntityFrameworkCore,
OpenTelemetry.Instrumentation.Process, and Npgsql.OpenTelemetry to the indicated
newer versions to ensure compatibility.
Replaces Expiration.KeepTtl with the actual expiry value and sets keepTtl to false in StringSetAsync. This ensures that the cache entry uses the intended expiration time instead of keeping the previous TTL.
Migrated all projects to target .NET 10.0, updated NuGet package versions across the solution, and replaced the legacy .sln file with a new .slnx format. CI/CD workflows and documentation were updated to reflect .NET 10.0 usage. Improved Swagger versioning configuration and fixed minor issues in Redis cache and AutoMapper registration.
Summary by Sourcery
Upgrade the framework to .NET 10 and refresh solution-wide configuration and infrastructure to align with the new runtime.
New Features:
Bug Fixes:
Enhancements:
Build:
CI:
Documentation:
Summary by CodeRabbit
New Features
Bug Fixes
Chores
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.