Skip to content

Cleanup | SqlConnectionFactory <- DbConnectionFactory #3435

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

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

benrr101
Copy link
Contributor

Description

This is the first PR in a bit of a fun experiment where we see if we can seriously clean up the codebase. According to @saurabh500 the codebase we've inherited dates back to the days when it was part of System.Data that not only contained the SqlClient but OdbcClient and even OracleClient. This is why there's Db* classes buried in the codebase that are passed around instead of the Sql* classes. In the best cases, these base implementations are fully abstract or just provide fallback implementations that throw. In the worst cases, they create confusing loops of implementations. And regardless, we are constantly passing them around as Db* and doing a lot of unnecessary checks and casts to the Sql* classes. These seemingly redundant base classes have a lot of unnecessary code and make the codebase as a whole more confusing. If we can do away with them, it would be idea. So, as an experiment, I decided SqlConnectionFactory might be a good place to see if we can simply merge the Db* class into the Sql* class.

As with most of my other merge project PRs, this one can be digested commit by commit (although be forewarned these ones are a bit stranger than usual due to protection levels). Important callouts have been added via my own review of the commit. Keep in mind although this could easily turn into a gigantic PR that removes all Db* classes, I've tried my best to be surgical and only eliminate the DbConnectionFactory class.

Issues

N/A

Testing

I'm still having trouble running test projects locally, so I have attempted to run them, but I can't guarantee I caught all the issues. CI will hopefully catch the remainder.

@benrr101 benrr101 added this to the 7.0-preview1 milestone Jun 23, 2025
@benrr101 benrr101 added the Code Health 💊 Issues/PRs that are targeted to source code quality improvements. label Jun 23, 2025
@Copilot Copilot AI review requested due to automatic review settings June 23, 2025 21:55
@benrr101 benrr101 added the P2 Use to label moderate priority issue - impacts atleast more than 1 customer. label Jun 23, 2025
@benrr101 benrr101 requested a review from a team as a code owner June 23, 2025 21:55
@benrr101 benrr101 changed the title Dev/russellben/cleanup/sqlconnectionfactory2 Cleanup | SqlConnectionFactory <- DbConnectionFactory Jun 23, 2025
Copy link
Contributor

@Copilot 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 replaces the legacy DbConnectionFactory abstractions with a single SqlConnectionFactory and cleans up related code, while also adding a new Timer overload.

  • Swaps all DbConnectionFactory references for SqlConnectionFactory and updates method signatures accordingly.
  • Introduces a TimeSpan-based overload for AdapterUtil.UnsafeCreateTimer.
  • Changes all SqlConnectionFactory.SingletonInstance usages to the new SqlConnectionFactory.Instance and removes now-unused compile links.

Reviewed Changes

Copilot reviewed 15 out of 17 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/WaitHandleDbConnectionPool.cs Switched to SqlConnectionFactory and updated pooled-connection call
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/IDbConnectionPool.cs Changed ConnectionFactory property to SqlConnectionFactory
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolGroup.cs Updated methods to accept SqlConnectionFactory
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs Adjusted ConnectionFactory property type
src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs Modified open/close schema methods to use SqlConnectionFactory
src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionClosed.cs Updated overrides to accept SqlConnectionFactory
src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs Added TimeSpan overload for UnsafeCreateTimer
src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs Revised TryReplaceConnection override signature
src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionHelper.cs Replaced SingletonInstance with Instance
src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs Swapped all SingletonInstance calls for Instance
src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj Removed DbConnectionFactory compile include
src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs Revised TryReplaceConnection override signature
src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionHelper.cs Replaced SingletonInstance with Instance
src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs Swapped SingletonInstance usage for Instance
src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj Removed DbConnectionFactory compile include
Comments suppressed due to low confidence (2)

src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs:136

  • The new TimeSpan-based overload should be covered by unit tests to verify correct timer creation and disposal behavior under different intervals.
        internal static Timer UnsafeCreateTimer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period)

src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs:133

  • [nitpick] Consider adding XML doc comments to both overloads to clarify the expected units for the int parameters and explain that the new overload accepts TimeSpans.
        internal static Timer UnsafeCreateTimer(TimerCallback callback, object state, int dueTime, int period) =>

Copy link
Contributor

@paulmedynski paulmedynski left a comment

Choose a reason for hiding this comment

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

I love removing unnecessary polymorphism! Just a few comments.

@@ -157,7 +157,7 @@ override protected DbCommand CreateDbCommand()
using (TryEventScope.Create("<prov.DbConnectionHelper.CreateDbCommand|API> {0}", ObjectID))
{
DbCommand command = null;
DbProviderFactory providerFactory = ConnectionFactory.ProviderFactory;
DbProviderFactory providerFactory = SqlConnectionFactory.ProviderFactory;
Copy link
Contributor

Choose a reason for hiding this comment

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

ProviderFactory always calls through to the singleton

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense to remove - my guess is it was some kinda thing where everything comes from the connection factory, implying that there's more than one kind of connection factory.

@@ -18,26 +22,562 @@

namespace Microsoft.Data.SqlClient
{
sealed internal class SqlConnectionFactory : DbConnectionFactory
Copy link
Contributor

Choose a reason for hiding this comment

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

I did find it useful to add stub implementations for DbConnectionFactory when writing unit tests for the connection pool. It's the best spot to stub opening a new connection. If this class becomes sealed, that pattern will break (can't even do inheritance and override). I'd consider adding an interface (It's just a bummer that this class has such an unnecessarily big API at the moment.)

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 agree. Singletons/static classes are always a kind of code smell - totally valid to have, but they should used as interfaces so they can be replaced in test scenarios (what I think of as a facade pattern).

I kinda don't want to try and implement an entire facade pattern as part of this change. I'll add a note to facade it. But what if I unseal the class for now?

paulmedynski
paulmedynski previously approved these changes Jul 2, 2025
Copy link

codecov bot commented Jul 2, 2025

Codecov Report

Attention: Patch coverage is 91.31737% with 29 lines in your changes missing coverage. Please review.

Project coverage is 64.73%. Comparing base (12f742d) to head (36ee48c).
Report is 17 commits behind head on main.

Files with missing lines Patch % Lines
...c/Microsoft/Data/SqlClient/SqlConnectionFactory.cs 91.24% 26 Missing ⚠️
.../Microsoft/Data/ProviderBase/DbConnectionClosed.cs 50.00% 2 Missing ⚠️
...core/src/Microsoft/Data/SqlClient/SqlConnection.cs 80.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3435      +/-   ##
==========================================
+ Coverage   63.51%   64.73%   +1.22%     
==========================================
  Files         293      279      -14     
  Lines       63810    62398    -1412     
==========================================
- Hits        40526    40396     -130     
+ Misses      23284    22002    -1282     
Flag Coverage Δ
addons 92.58% <ø> (ø)
netcore 68.96% <91.15%> (+2.02%) ⬆️
netfx 66.20% <91.38%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Code Health 💊 Issues/PRs that are targeted to source code quality improvements. P2 Use to label moderate priority issue - impacts atleast more than 1 customer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants