Skip to content

Conversation

@yilmaztayfun
Copy link
Contributor

@yilmaztayfun yilmaztayfun commented Jan 19, 2026

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:

  • Introduce centralized Swagger configuration using the options pattern to support API versioned documentation.

Bug Fixes:

  • Fix keyed service resolution by using the keyed service provider interface to cache keyed services correctly.
  • Correct Redis cache serialization and key TTL handling to avoid deserialization issues and preserve existing expirations.

Enhancements:

  • Adjust AutoMapper registration to use the newer configuration overload while preserving existing mapping assemblies.

Build:

  • Update the solution to use the new .slnx format and retarget all projects and SDK settings to .NET 10.
  • Refresh NuGet package versions across the solution to versions compatible with .NET 10.

CI:

  • Update GitHub Actions workflows to build, restore, and analyze the new .slnx solution using the .NET 10 SDK only.

Documentation:

  • Update README badges and documentation references to reflect .NET 10 as the targeted runtime.

Summary by CodeRabbit

  • New Features

    • Improved API documentation: versioned Swagger/OpenAPI support
  • Bug Fixes

    • Fixed distributed cache behavior
    • Improved keyed service provider compatibility
  • Chores

    • Upgraded framework and projects to .NET 10.0
    • Updated many dependencies to newer stable versions
  • Documentation

    • Updated .NET version badge in README.md

✏️ Tip: You can customize this high-level summary in your review settings.

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.
@yilmaztayfun yilmaztayfun self-assigned this Jan 19, 2026
@yilmaztayfun yilmaztayfun requested review from a team as code owners January 19, 2026 20:01
@yilmaztayfun yilmaztayfun requested a review from mokoker January 19, 2026 20:01
@yilmaztayfun yilmaztayfun linked an issue Jan 19, 2026 that may be closed by this pull request
@sourcery-ai
Copy link

sourcery-ai bot commented Jan 19, 2026

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 ConfigureOptions

sequenceDiagram
    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
Loading

Sequence diagram for updated Redis cache get and set operations

sequenceDiagram
    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
Loading

Class diagram for updated Swagger versioning and DI configuration

classDiagram
    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
Loading

Class diagram for updated caching and AutoMapper registration

classDiagram
    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
Loading

File-Level Changes

Change Details Files
.NET SDK and solution upgrade to .NET 10 including project and package updates plus new .slnx solution file.
  • Updated global.json to require .NET SDK 10.0.102.
  • Updated the README .NET badge to advertise .NET 10.0 only.
  • Replaced the legacy BBT.Aether.sln with a new BBT.Aether.slnx solution file.
  • Adjusted all framework project and shared props files to target .NET 10 and align NuGet package versions (see csproj/props changes).
global.json
README.md
framework/BBT.Aether.sln
framework/BBT.Aether.slnx
Directory.Packages.props
common.props
framework/src/BBT.Aether.Abstractions/BBT.Aether.Abstractions.csproj
framework/src/BBT.Aether.Application/BBT.Aether.Application.csproj
framework/src/BBT.Aether.AspNetCore/BBT.Aether.AspNetCore.csproj
framework/src/BBT.Aether.Aspects/BBT.Aether.Aspects.csproj
framework/src/BBT.Aether.Cli/BBT.Aether.Cli.csproj
framework/src/BBT.Aether.Core/BBT.Aether.Core.csproj
framework/src/BBT.Aether.Domain/BBT.Aether.Domain.csproj
framework/src/BBT.Aether.HttpClient/BBT.Aether.HttpClient.csproj
framework/src/BBT.Aether.Infrastructure/BBT.Aether.Infrastructure.csproj
framework/src/BBT.Aether.TestBase/BBT.Aether.TestBase.csproj
CI workflows updated to use .NET 10 SDK and new .slnx solution.
  • Updated publish-nuget workflow to install only the 10.0.x SDK and to restore/build BBT.Aether.slnx instead of the old .sln.
  • Updated check-sonar workflow to build BBT.Aether.slnx instead of the removed .sln.
.github/workflows/publish-nuget.yml
.github/workflows/check-sonar.yml
Swagger configuration refactored to use the ConfigureOptions pattern with API version-aware documents.
  • Added SwaggerGen registration without inline configuration in AddAetherApiVersioning.
  • Introduced ConfigureSwaggerOptions implementing IConfigureOptions that uses IApiVersionDescriptionProvider to register one OpenApiInfo per API version.
  • Switched to Swashbuckle.AspNetCore.SwaggerGen and Microsoft.Extensions.Options namespaces and removed the direct provider build from the service collection.
framework/src/BBT.Aether.AspNetCore/Microsoft/Extensions/DependencyInjection/AetherApiVersioningServiceCollectionExtensions.cs
AutoMapper registration updated to the newer AddAutoMapper overload while preserving assembly scanning and object mapper registrations.
  • Changed AddAetherAutoMapperMapper to call AddAutoMapper with a configuration action and the discovered assemblies rather than only the assemblies array.
  • Kept IObjectMapper and generic IObjectMapper<,> registrations intact.
framework/src/BBT.Aether.Infrastructure/Microsoft/Extensions/DependencyInjection/AetherMapperServiceCollectionExtensions.cs
Keyed DI cache and Redis distributed cache behavior adjusted for updated .NET/StackExchange.Redis APIs.
  • Changed CachedServiceProviderBase to cast ServiceProvider to IKeyedServiceProvider before calling GetKeyedService and GetRequiredKeyedService to align with the new keyed service provider API.
  • Fixed RedisDistributedCacheService deserialization to cast cachedValue to string before JsonSerializer.Deserialize.
  • Changed RedisDistributedCacheService to use Expiration.KeepTtl when writing values with StringSetAsync, relying on Redis TTL rather than recalculating expiry.
framework/src/BBT.Aether.Core/BBT/Aether/DependencyInjection/CachedServiceProviderBase.cs
framework/src/BBT.Aether.Infrastructure/BBT/Aether/DistributedCache/Redis/RedisDistributedCacheService.cs

Assessment against linked issues

Issue Objective Addressed Explanation
#41 Update all projects in the BBT Workflow Engine to target .NET 10.0 LTS (including SDK selection and project target frameworks).
#41 Update tooling, CI/CD workflows, and documentation to reflect .NET 10.0 usage.

Possibly linked issues

  • #N/A: PR performs the .NET 10 LTS migration requested, updating targets, SDK version, workflows, and related dependencies.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link

coderabbitai bot commented Jan 19, 2026

Note

Other AI code review bot(s) detected

CodeRabbit 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

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'review'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • 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
📝 Walkthrough

Walkthrough

This PR upgrades the repository to .NET 10.0 (global.json and project TargetFrameworks), replaces the solution file with framework/BBT.Aether.slnx, performs a broad NuGet package version uplift, adjusts build workflows to use the new solution, and adds small code changes for Swagger options, keyed service resolution, AutoMapper, and Redis TTL handling.

Changes

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.0net10.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
Loading

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 .slnx delight,
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 ⚠️ Warning 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @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

  • .NET 10.0 Upgrade: All projects within the solution have been migrated to target .NET 10.0, ensuring compatibility with the latest framework features and performance improvements.
  • Dependency Updates: Numerous NuGet packages, including Autofac, AutoMapper, Dapr, Microsoft.AspNetCore.*, EntityFrameworkCore, OpenTelemetry, and PostSharp, have been updated to their latest compatible versions.
  • Solution File Format Migration: The legacy .sln solution file has been replaced with the newer .slnx format, streamlining solution management.
  • Improved Swagger API Versioning: The Swagger configuration for API versioning has been refactored to use the IConfigureOptions pattern, enhancing extensibility and maintainability.
  • Redis Cache Fixes: Addressed issues in the Redis distributed cache service, including explicit casting during deserialization and ensuring StringSetAsync preserves Time-To-Live (TTL).
  • AutoMapper Registration Adjustment: The AutoMapper registration process has been updated to align with modern configuration practices.

🧠 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
  • Ignored by pattern: .github/workflows/** (2)
    • .github/workflows/check-sonar.yml
    • .github/workflows/publish-nuget.yml
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@sourcery-ai sourcery-ai bot left a 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 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.
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>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link

@gemini-code-assist gemini-code-assist bot left a 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);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

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

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: 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 expiry value is computed from options (lines 60-67) but completely ignored. Expiration.KeepTtl preserves the existing TTL on the key rather than applying the new expiration. This means:

  1. New keys will have no expiration (infinite TTL)
  2. Existing keys will retain their old TTL, ignoring caller-specified options
  3. 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)ServiceProvider violates the class's interface contract. CachedServiceProviderBase implements ICachedServiceProviderBase : IKeyedServiceProvider, which commits to supporting keyed services, but the property accepts any IServiceProvider. If a provider that doesn't implement IKeyedServiceProvider is passed, the cast throws InvalidCastException with no context.

The codebase already provides a safe pattern in ServiceProviderKeyedServiceExtensions using is checks and descriptive InvalidOperationException messages. 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 IKeyedServiceProvider to 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-dotnet action to ensure the .NET 10.0 SDK is available. The windows-latest runner 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 analyze
framework/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 legacy AssetTargetFallback.

The portable-net45+win8+wp8+wpa81 fallback 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 AddAutoMapper overloads require an Action<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 legacy AssetTargetFallback.

The portable-net45+win8+wp8+wpa81 fallback 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 .NETStandard conditionals.

These ItemGroup blocks are conditioned on TargetFrameworkIdentifier == '.NETStandard', but the project now exclusively targets net10.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.Json is at 8.0.5 while related packages have been updated to 10.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.2 for 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" />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for ResponseCompression usage in the codebase
rg -n 'ResponseCompression|UseResponseCompression|AddResponseCompression' --type=cs

Repository: 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 -20

Repository: 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 -20

Repository: 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" />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 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" />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 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.

Comment on lines 192 to 194
<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" />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 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.props

Repository: 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 -20

Repository: 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}")
EOF

Repository: 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.
@yilmaztayfun yilmaztayfun merged commit 2b7aa90 into master Jan 19, 2026
5 of 6 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jan 19, 2026
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.

Upgrade to .NET 10 (LTS)

2 participants