Skip to content

Conversation

@benrr101
Copy link
Contributor

Description

Introduced _WINDOWS/_UNIX compile-time constants and TargetOs selection in src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj, plus mirrored updates to netcore/src/Microsoft.Data.SqlClient.csproj and netfx/src/Microsoft.Data.SqlClient.csproj so OS-gated code can be compiled from the common project and Windows-only ILLink substitutions are conditionally embedded (Resources/ILLink.Substitutions.xml).

Normalized OS-specific sources to .windows/.unix naming and wired them into the new flags (e.g., LocalDbApi., LocalDB.netcore., PacketHandle., SessionHandle., SqlFileStream., SqlColumnEncryption, TdsParser*, SNI interop files), with new netfx-specific shims like PacketHandle.netfx.cs and SessionHandle.netfx.cs. Refactored shared helpers into OS- and target-aware partials: AdapterUtil.cs now delegates netfx- and netcore-specific pieces to AdapterUtil.netfx.cs/AdapterUtil.netcore.cs; DbConnectionPoolIdentity.cs and SqlDataSourceEnumerator.cs now pick managed vs native implementations based on _WINDOWS/_UNIX and LocalAppContextSwitches.UseManagedNetworking; added netfx-only System/Diagnostics/CodeAnalysis.netfx.cs.

Folded the netcore app–specific SSL over TDS stream logic into ManagedSni/SslOverTdsStream.netcore.cs, adding span-based sync/async read handling and packet encapsulation directly in the shared file.

Tidied LocalAppContextSwitches.cs for clearer NET vs NETFRAMEWORK behavior (globalization invariant handling and managed SNI defaults) under the new OS constants.

[The above is AI generated]

Issues

Continuation of work from #1261

Testing

Projects still build, and the common project is building too 👀

…o methods that had separate implementations were identical...
…partial.

This file is too big to come up with a consistent way to split all this stuff up.
…c class.

Cleaned up some code (removed redundant parentheses, split some long lines, removed always-false variables)
…ssionHandle.netfx. This really makes these classes easier to read.
… add comment explaining why this file exists.
Copilot AI review requested due to automatic review settings November 26, 2025 00:34
Copilot finished reviewing on behalf of benrr101 November 26, 2025 00:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces compile-time OS constants (_WINDOWS/_UNIX) to consolidate platform-specific code across the Microsoft.Data.SqlClient project. The refactoring normalizes file naming conventions to .windows/.unix suffixes, eliminates separate platform-specific partial files in favor of conditional compilation within shared files, and updates project files to support cross-platform builds from a unified source tree. Key changes include merging AdapterUtil.Windows.cs/AdapterUtil.Unix.cs into the main file with OS guards, consolidating DbConnectionPoolIdentity platform variants, and folding .NET Core app-specific SSL stream logic into the main implementation.

Key Changes:

  • Introduced _WINDOWS and _UNIX preprocessor constants based on TargetOs in project files
  • Normalized OS-specific file naming from .Windows/.Unix to .windows/.unix
  • Consolidated platform-specific partial classes into shared files with #if directives
  • Refactored PacketHandle and SessionHandle to use platform-specific files with improved documentation

Reviewed changes

Copilot reviewed 84 out of 86 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
System/Diagnostics/CodeAnalysis.netfx.cs Extracted NETFRAMEWORK-only attributes to separate file
System/Diagnostics/CodeAnalysis.cs Removed file (content moved to .netfx variant)
Resources/ILLink.Substitutions.xml Changed from Unix-specific to Windows-specific with feature flags
Resources/ILLink.Substitutions.Unix.xml Removed (consolidated into main file with OS conditions)
SqlFileStream.windows.cs Added _WINDOWS guard and TODO comment
TdsParser*.windows.cs Added _WINDOWS guards and formatting improvements
PacketHandle/SessionHandle variants Created platform-specific shims with improved documentation
SslOverTdsStream files Merged NetCoreApp.cs into netcore.cs with all I/O methods
AdapterUtil.cs + variants Consolidated Windows/Unix partials into main file with OS guards
DbConnectionPoolIdentity.cs Merged Windows/Unix variants with conditional logic
SqlDataSourceEnumerator.cs Unified platform selection logic in main file
LocalAppContextSwitches.cs Added NETFRAMEWORK GlobalizationInvariantMode stub, clarified OS-specific UseManagedNetworking
Project files Added TargetOs properties and _WINDOWS/_UNIX constant definitions

Copy link
Contributor

@edwardneal edwardneal left a comment

Choose a reason for hiding this comment

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

Very early review here, but the comment in SqlColumnEncryptionCspProvider has wider implications - how much of the work needs to be done at compile time? Could we replace the conditional compilations with runtime OS checks?

If that works then we could eliminate the need to build and package for multiple OSes completely.

Comment on lines 44 to 45
<DefineConstants Condition="'$(OSGroup.ToUpper())'=='UNIX'">_UNIX</DefineConstants>
<DefineConstants Condition="'$(OSGroup.ToUpper())'=='WINDOWS_NT'">_WINDOWS</DefineConstants>
Copy link
Contributor

Choose a reason for hiding this comment

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

There are likely to be other points to untangle, but netcore automatically defines the appropriate WINDOWS preprocessor symbol. It might be better to polyfill this in the netfx project rather than define a new one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

While true, as far as I know, there's no way to override those. We want to be able to build unix on windows and windows on unix (and to a lesser extent want to be able to get IDE highlighting for one on the other), so we need a flag that can be overridden. This seems like the best way to do it, as per the internet :)

<Link>Resources\ILLink.Substitutions.Unix.xml</Link>
<EmbeddedResource Include="$(CommonSourceRoot)Resources\Microsoft.Data.SqlClient.SqlMetaData.xml">
<Link>Resources\Microsoft.Data.SqlCLient.SqlMetaData.xml</Link>
<LogicalName>Microsoft.Data.SqlClient.SqlMetaData.xml</LogicalName> <!-- @TODO: How necessary is this? -->
Copy link
Contributor

Choose a reason for hiding this comment

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

It's not necessary, the code to replace it is just bulky - #3372

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Haha, I was specifically calling out the logical name tag, but yeah if we can junk the xml file altogether I'd approve of it.

// See the LICENSE file in the project root for more information.

#if NETFRAMEWORK
#if NETFRAMEWORK && _WINDOWS
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't NETFRAMEWORK imply Windows-only code?
(here and elsewhere)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, probably ... I'm a bit torn on these. I think no matter which way it's done, it's a little confusing.

Comment on lines +5 to +6
// @TODO: Introduce polymorphism to remove need for this level of indirection
// @TODO: Also, why do we have any other type besides managed defined here?
Copy link
Contributor

Choose a reason for hiding this comment

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

PacketHandles are used to transport either native or managed packets around TdsParserStateObject.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know we discussed this before, but I'm still not convinced ... so I left these comments to consider it further.
But considering on unix, we never have native packets, I don't know why we need to have an object with both types defined.

Comment on lines -4 to -5
<!-- The Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows switch must always be true on Unix platforms. -->
<method signature="System.Boolean get_UseManagedNetworking()" body="stub" value="true" />
Copy link
Contributor

Choose a reason for hiding this comment

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

This is different to the Windows ILLink.Substitutions.xml resource, and shouldn't be disregarded.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, but all it does is hard code UseManagedNetworking to true on unix - which at the time wasn't defined in the app context switches. We can do that with code that can be switched on/off via pre-compiler flags and eliminate a file that would confuse the heck out of someone unfamiliar with it.

Copy link
Contributor

@edwardneal edwardneal Nov 26, 2025

Choose a reason for hiding this comment

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

The original reason for having two files was to block someone from switching off the managed SNI on Linux using the below RuntimeHostConfigurationOption in their client application's csproj when trying to publish in a trimmed environment:

<RuntimeHostConfigurationOption
    Include="Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows"
    value="false"
/>

On second thoughts though, I don't think the use of the Windows ILLink.Substitutions.xml resource will cause a problem - it's just a guardrail on invalid usage of the library, trimming isn't technically supported yet, and this could be wrapped up in a runtime-level OS check.

@benrr101
Copy link
Contributor Author

@edwardneal As to your overall comment that it would be nice to eliminate the compile-time checks: yes, yes it would be nice :) @paulmedynski and I chatted about it and I think we came to the conclusion that this was a decent enough solution for now. A lot exists because we have native SNI - and it'd be nice if we can deprecate native SNI.

@paulmedynski
Copy link
Contributor

We will be auditing the compile-time checks (not as part of this PR) to see how many of them could become inexpensive runtime checks (i.e. checked once per runtime, or "not often"). If the runtime costs are very low, then we would consider converting them in order to gain project architecture efficiencies and eliminate a large chunk of the build setup that exists to support OS-specific artifacts.

@benrr101 benrr101 changed the title Dev/russellben/os flags Merge | OS Flags Nov 26, 2025
@edwardneal
Copy link
Contributor

edwardneal commented Nov 26, 2025

Thanks - that sounds good. The JIT will lift the OS-level checks via OperatingSystem.IsWindows in Release configuration, so they're very cheap and probably don't need to be cached (see SharpLab examples for netcore and netfx.)

@paulmedynski paulmedynski self-assigned this Nov 27, 2025
Copilot AI review requested due to automatic review settings December 1, 2025 19:30
Copilot finished reviewing on behalf of benrr101 December 1, 2025 19:31
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 81 out of 83 changed files in this pull request and generated no new comments.

paulmedynski
paulmedynski previously approved these changes Dec 1, 2025
…at are platform specific in

Fix case-sensitivity issues in netfx project
Copilot AI review requested due to automatic review settings December 2, 2025 19:45
Copilot finished reviewing on behalf of benrr101 December 2, 2025 19:46
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 83 out of 85 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Common Project 🚮 Things that relate to the common project project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants