Conversation
There was a problem hiding this comment.
Pull request overview
This PR aims to enable Nullable Reference Types (NRT) across the Azure App Configuration .NET Provider codebase to address issue #300 (“Add nullable annotations”), improving null-safety and consumer-facing nullability metadata.
Changes:
- Enabled NRT at the project level (
<Nullable>enable</Nullable>) in the main provider and related packages. - Annotated numerous model/options/API surfaces with nullable reference types and added non-null default initializers where appropriate.
- Updated several method signatures (e.g.,
Equals(object? obj),outparameters) to align with NRT conventions.
Reviewed changes
Copilot reviewed 39 out of 39 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/TracingUtils.cs | Adds #nullable disable at file scope. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/SnapshotReference/SnapshotReference.cs | Initializes SnapshotName to a non-null default. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/RequestTracingOptions.cs | Marks version properties nullable. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/PushNotification.cs | Marks event fields nullable for NRT consumers. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Models/KeyValueWatcher.cs | Adds defaults/nullable annotations; updates Equals(object? ...). |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Models/KeyValueSelector.cs | Marks selector filters nullable; updates Equals(object? ...). |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Models/KeyValueIdentifier.cs | Makes Label nullable; updates ctor and Equals(object? ...). |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Microsoft.Extensions.Configuration.AzureAppConfiguration.csproj | Enables <Nullable>enable</Nullable>. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Logger.cs | Marks backing logger field nullable. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/KeyValueChange.cs | Makes several properties nullable. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/IKeyValueAdapter.cs | Allows nullable optional parameter for OnChangeDetected. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/JsonFlattener.cs | Initializes _currentPath to a non-null default. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureVariant.cs | Adds defaults/nullable annotations. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureUserAllocation.cs | Marks fields nullable. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureTelemetry.cs | Marks Metadata nullable. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeaturePercentileAllocation.cs | Marks Variant nullable. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureManagementKeyValueAdapter.cs | Adds #nullable disable at file scope. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureGroupAllocation.cs | Marks fields nullable. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlagOptions.cs | Marks label/tag filters nullable where optional. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlag.cs | Adds defaults/nullable annotations. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureConditions.cs | Marks RequirementType nullable. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureAllocation.cs | Marks allocation fields nullable. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/ClientFilter.cs | Initializes Name to a non-null default. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/StringExtensions.cs | Updates parsing helpers to use nullable out/return types. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/EventGridEventExtensions.cs | Updates out parameter nullability and local nullability. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Exceptions/KeyVaultReferenceException.cs | Marks exception detail properties nullable. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/EndpointComparer.cs | Updates Equals(Uri?, Uri?) signature for NRT. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/ConfigurationClientManager.cs | Adds #nullable disable at file scope. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/CachedKeyVaultSecret.cs | Marks fields/ctor args nullable; updates SourceId to nullable. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultSecretProvider.cs | Adds #nullable disable at file scope. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultKeyValueAdapter.cs | Adds #nullable disable at file scope. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationSource.cs | Makes local provider nullable. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationProvider.cs | Adds #nullable disable at file scope. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationOptions.cs | Annotates internal fields nullable; ensures adapters list not null. |
| src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationKeyVaultOptions.cs | Marks internal credential/resolver nullable. |
| src/Microsoft.Azure.AppConfiguration.Functions.Worker/Microsoft.Azure.AppConfiguration.Functions.Worker.csproj | Enables <Nullable>enable</Nullable>. |
| src/Microsoft.Azure.AppConfiguration.Functions.Worker/AzureAppConfigurationRefreshExtensions.cs | Marks retrieved service as nullable. |
| src/Microsoft.Azure.AppConfiguration.AspNetCore/Microsoft.Azure.AppConfiguration.AspNetCore.csproj | Enables <Nullable>enable</Nullable>. |
| src/Microsoft.Azure.AppConfiguration.AspNetCore/AzureAppConfigurationRefreshExtensions.cs | Marks retrieved service as nullable and casts accordingly. |
Comments suppressed due to low confidence (1)
src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/StringExtensions.cs:16
TryParseContentTypecurrently requires a non-nullcontentTypeString, but the implementation explicitly handles null/whitespace and sets the out value to null. Consider changing the receiver tostring?to match actual behavior and make call-sites (e.g.,ConfigurationSetting.ContentType) easier to annotate under NRT. Also, since the out parameter is now nullable, call sites should useContentType?(or a null check after a successful return) to avoid nullable warnings/possible null assignments.
public static bool TryParseContentType(this string contentTypeString, out ContentType? contentType)
{
contentType = null;
if (string.IsNullOrWhiteSpace(contentTypeString))
{
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT license. | ||
| // | ||
| #nullable disable |
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT license. | ||
| // | ||
| #nullable disable |
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT license. | ||
| // | ||
| #nullable disable |
| bool CanProcess(ConfigurationSetting setting); | ||
|
|
||
| void OnChangeDetected(ConfigurationSetting setting = null); | ||
| void OnChangeDetected(ConfigurationSetting? setting = null); |
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT license. | ||
| // | ||
| #nullable disable |
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT license. | ||
| // | ||
| #nullable disable |
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT license. | ||
| // | ||
| #nullable disable |
| public string Key { get; set; } | ||
|
|
||
| public string Label { get; set; } | ||
| public string? Label { get; set; } | ||
|
|
||
| public ConfigurationSetting Current { get; set; } | ||
| public ConfigurationSetting? Current { get; set; } |
|
Nullable mark should not be abused. NRT should be used to express the design intent. All of our C# code bases don't use What we should do is to add more null check and throw the correct exception (intead of NRE). |
| } | ||
|
|
||
| IConfigurationRefresherProvider refresherProvider = (IConfigurationRefresherProvider)builder.ApplicationServices.GetService(typeof(IConfigurationRefresherProvider)); | ||
| IConfigurationRefresherProvider? refresherProvider = (IConfigurationRefresherProvider?)builder.ApplicationServices.GetService(typeof(IConfigurationRefresherProvider)); |
There was a problem hiding this comment.
I don't think we need to make IConfigurationRefresherProvider nullable here. We have null check below, correct exception will be thrown
|
|
||
| <PropertyGroup> | ||
| <TargetFrameworks>net8.0;net9.0</TargetFrameworks> | ||
| <Nullable>enable</Nullable> |
There was a problem hiding this comment.
None of our C# code bases and even .NET azure SDKs don't set Nullable to enable (the default value is disable). If we want to set it explicitly, it should be disable
| ///// The value of the Key Vault secret. | ||
| ///// </summary> | ||
| public string SecretValue { get; set; } | ||
| public string? SecretValue { get; set; } |
There was a problem hiding this comment.
Adding ? doesn't correctly express the design intent, the SecretValue should not be null for CachedKeyValueSecret
fix issue #300