diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index af0db1e61f..89fbdaa759 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -591,6 +591,9 @@ Microsoft\Data\SqlClient\SqlConnectionEncryptOptionConverter.cs + + Microsoft\Data\SqlClient\SqlConnectionFactory.cs + Microsoft\Data\SqlClient\SqlConnectionString.cs @@ -806,10 +809,8 @@ - - diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs deleted file mode 100644 index e3b2ba9438..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Reflection; -using System.Runtime.Loader; - -namespace Microsoft.Data.SqlClient -{ - internal sealed partial class SqlConnectionFactory - { - partial void SubscribeToAssemblyLoadContextUnload() - { - AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading += SqlConnectionFactoryAssemblyLoadContext_Unloading; - } - - private void SqlConnectionFactoryAssemblyLoadContext_Unloading(AssemblyLoadContext obj) - { - Unload(obj, EventArgs.Empty); - } - } -} diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 1fb9fce27e..78466acbc2 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -741,6 +741,9 @@ Microsoft\Data\SqlClient\SqlConnectionEncryptOptionConverter.cs + + Microsoft\Data\SqlClient\SqlConnectionFactory.cs + Microsoft\Data\SqlClient\SqlConnectionString.cs @@ -951,7 +954,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs deleted file mode 100644 index 56f086e590..0000000000 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs +++ /dev/null @@ -1,347 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Data.Common; -using System.Diagnostics; -using System.IO; -using Microsoft.Data.Common; -using Microsoft.Data.Common.ConnectionString; -using Microsoft.Data.ProviderBase; -using Microsoft.Data.SqlClient.ConnectionPool; -using Microsoft.Data.SqlClient.Server; - -namespace Microsoft.Data.SqlClient -{ - sealed internal class SqlConnectionFactory : DbConnectionFactory - { - private SqlConnectionFactory() : base() - { - } - - public static readonly SqlConnectionFactory SingletonInstance = new SqlConnectionFactory(); - private const string _metaDataXml = "MetaDataXml"; - - override public DbProviderFactory ProviderFactory - { - get - { - return SqlClientFactory.Instance; - } - } - - protected override DbConnectionInternal CreateConnection( - DbConnectionOptions options, - DbConnectionPoolKey poolKey, - DbConnectionPoolGroupProviderInfo poolGroupProviderInfo, - IDbConnectionPool pool, - DbConnection owningConnection) - { - return CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection, userOptions: null); - } - - protected override DbConnectionInternal CreateConnection( - DbConnectionOptions options, - DbConnectionPoolKey poolKey, - DbConnectionPoolGroupProviderInfo poolGroupProviderInfo, - IDbConnectionPool pool, - DbConnection owningConnection, - DbConnectionOptions userOptions) - { - SqlConnectionString opt = (SqlConnectionString)options; - SqlConnectionPoolKey key = (SqlConnectionPoolKey)poolKey; - SessionData recoverySessionData = null; - - SqlConnection sqlOwningConnection = owningConnection as SqlConnection; - bool applyTransientFaultHandling = sqlOwningConnection?._applyTransientFaultHandling ?? false; - - SqlConnectionString userOpt = null; - if (userOptions != null) - { - userOpt = (SqlConnectionString)userOptions; - } - else if (sqlOwningConnection != null) - { - userOpt = (SqlConnectionString)sqlOwningConnection.UserConnectionOptions; - } - - if (sqlOwningConnection != null) - { - recoverySessionData = sqlOwningConnection._recoverySessionData; - } - - bool redirectedUserInstance = false; - DbConnectionPoolIdentity identity = null; - - // Pass DbConnectionPoolIdentity to SqlInternalConnectionTds if using integrated security. - // Used by notifications. - if (opt.IntegratedSecurity || opt.Authentication == SqlAuthenticationMethod.ActiveDirectoryIntegrated) - { - if (pool != null) - { - identity = pool.Identity; - } - else - { - identity = DbConnectionPoolIdentity.GetCurrent(); - } - } - - // FOLLOWING IF BLOCK IS ENTIRELY FOR SSE USER INSTANCES - // If "user instance=true" is in the connection string, we're using SSE user instances - if (opt.UserInstance) - { - // opt.DataSource is used to create the SSE connection - redirectedUserInstance = true; - string instanceName; - - if (pool == null || (pool != null && pool.Count <= 0)) - { // Non-pooled or pooled and no connections in the pool. - - SqlInternalConnectionTds sseConnection = null; - try - { - // What about a failure - throw? YES! - // BUG (VSTFDevDiv) 479687: Using TransactionScope with Linq2SQL against user instances fails with "connection has been broken" message - // NOTE: Cloning connection option opt to set 'UserInstance=True' and 'Enlist=False' - // This first connection is established to SqlExpress to get the instance name - // of the UserInstance. - SqlConnectionString sseopt = new SqlConnectionString(opt, opt.DataSource, true /* user instance=true */, false /* set Enlist = false */); - sseConnection = new SqlInternalConnectionTds(identity, sseopt, key.Credential, null, "", null, false, applyTransientFaultHandling: applyTransientFaultHandling); - // NOTE: Retrieve here. This user instance name will be used below to connect to the Sql Express User Instance. - instanceName = sseConnection.InstanceName; - - // Set future transient fault handling based on connection options - sqlOwningConnection._applyTransientFaultHandling = opt != null && opt.ConnectRetryCount > 0; - - if (!instanceName.StartsWith("\\\\.\\", StringComparison.Ordinal)) - { - throw SQL.NonLocalSSEInstance(); - } - - if (pool != null) - { // Pooled connection - cache result - SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo; - // No lock since we are already in creation mutex - providerInfo.InstanceName = instanceName; - } - } - finally - { - if (sseConnection != null) - { - sseConnection.Dispose(); - } - } - } - else - { // Cached info from pool. - SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo; - // No lock since we are already in creation mutex - instanceName = providerInfo.InstanceName; - } - - // NOTE: Here connection option opt is cloned to set 'instanceName=' that was - // retrieved from the previous SSE connection. For this UserInstance connection 'Enlist=True'. - // options immutable - stored in global hash - don't modify - opt = new SqlConnectionString( - opt, - instanceName, - userInstance: false, - setEnlistValue: null); // Do not modify the enlist value - poolGroupProviderInfo = null; - } - - return new SqlInternalConnectionTds( - identity, - opt, - key.Credential, - poolGroupProviderInfo, - newPassword: string.Empty, - newSecurePassword: null, - redirectedUserInstance, - userOpt, - recoverySessionData, - applyTransientFaultHandling, - key.AccessToken, - pool, - key.AccessTokenCallback); - } - - protected override DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous) - { - Debug.Assert(!string.IsNullOrEmpty(connectionString), "empty connectionString"); - SqlConnectionString result = new SqlConnectionString(connectionString); - return result; - } - - internal override DbConnectionPoolProviderInfo CreateConnectionPoolProviderInfo(DbConnectionOptions connectionOptions) - { - DbConnectionPoolProviderInfo providerInfo = null; - - if (((SqlConnectionString)connectionOptions).UserInstance) - { - providerInfo = new SqlConnectionPoolProviderInfo(); - } - - return providerInfo; - } - - protected override DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions(DbConnectionOptions connectionOptions) - { - SqlConnectionString opt = (SqlConnectionString)connectionOptions; - - DbConnectionPoolGroupOptions poolingOptions = null; - - if (opt.Pooling) - { // never pool context connections. - int connectionTimeout = opt.ConnectTimeout; - - if (connectionTimeout > 0 && connectionTimeout < int.MaxValue / 1000) - { - connectionTimeout *= 1000; - } - else if (connectionTimeout >= int.MaxValue / 1000) - { - connectionTimeout = int.MaxValue; - } - - if (opt.Authentication == SqlAuthenticationMethod.ActiveDirectoryInteractive) - { - // interactive mode will always have pool's CreateTimeout = 10 x ConnectTimeout. - if (connectionTimeout >= Int32.MaxValue / 10) - { - connectionTimeout = Int32.MaxValue; - } - else - { - connectionTimeout *= 10; - } - SqlClientEventSource.Log.TryTraceEvent("Set connection pool CreateTimeout={0} when AD Interactive is in use.", connectionTimeout); - } - - poolingOptions = new DbConnectionPoolGroupOptions( - opt.IntegratedSecurity || opt.Authentication == SqlAuthenticationMethod.ActiveDirectoryIntegrated, - opt.MinPoolSize, - opt.MaxPoolSize, - connectionTimeout, - opt.LoadBalanceTimeout, - opt.Enlist); - } - return poolingOptions; - } - - override protected DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal internalConnection, out bool cacheMetaDataFactory) - { - Debug.Assert(internalConnection != null, "internalConnection may not be null."); - - Stream xmlStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("Microsoft.Data.SqlClient.SqlMetaData.xml"); - cacheMetaDataFactory = true; - - Debug.Assert(xmlStream != null, nameof(xmlStream) + " may not be null."); - - return new SqlMetaDataFactory(xmlStream, - internalConnection.ServerVersion, - internalConnection.ServerVersion); //internalConnection.ServerVersionNormalized); - } - - internal override DbConnectionPoolGroupProviderInfo CreateConnectionPoolGroupProviderInfo( - DbConnectionOptions connectionOptions) - { - return new SqlConnectionPoolGroupProviderInfo((SqlConnectionString)connectionOptions); - } - - internal static SqlConnectionString FindSqlConnectionOptions(SqlConnectionPoolKey key) - { - SqlConnectionString connectionOptions = (SqlConnectionString)SingletonInstance.FindConnectionOptions(key); - if (connectionOptions == null) - { - connectionOptions = new SqlConnectionString(key.ConnectionString); - } - if (connectionOptions.IsEmpty) - { - throw ADP.NoConnectionString(); - } - return connectionOptions; - } - - override internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnection connection) - { - SqlConnection c = (connection as SqlConnection); - if (c != null) - { - return c.PoolGroup; - } - return null; - } - - override internal DbConnectionInternal GetInnerConnection(DbConnection connection) - { - SqlConnection c = (connection as SqlConnection); - if (c != null) - { - return c.InnerConnection; - } - return null; - } - - override protected int GetObjectId(DbConnection connection) - { - SqlConnection c = (connection as SqlConnection); - if (c != null) - { - return c.ObjectID; - } - return 0; - } - - override internal void PermissionDemand(DbConnection outerConnection) - { - SqlConnection c = (outerConnection as SqlConnection); - if (c != null) - { - c.PermissionDemand(); - } - } - - override internal void SetConnectionPoolGroup(DbConnection outerConnection, DbConnectionPoolGroup poolGroup) - { - SqlConnection c = (outerConnection as SqlConnection); - if (c != null) - { - c.PoolGroup = poolGroup; - } - } - - override internal void SetInnerConnectionEvent(DbConnection owningObject, DbConnectionInternal to) - { - SqlConnection c = (owningObject as SqlConnection); - if (c != null) - { - c.SetInnerConnectionEvent(to); - } - } - - override internal bool SetInnerConnectionFrom(DbConnection owningObject, DbConnectionInternal to, DbConnectionInternal from) - { - SqlConnection c = (owningObject as SqlConnection); - if (c != null) - { - return c.SetInnerConnectionFrom(to, from); - } - return false; - } - - override internal void SetInnerConnectionTo(DbConnection owningObject, DbConnectionInternal to) - { - SqlConnection c = (owningObject as SqlConnection); - if (c != null) - { - c.SetInnerConnectionTo(to); - } - } - - } -} - diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs index a771f000d5..399b98435b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs @@ -642,23 +642,13 @@ internal void QueuePoolGroupForRelease(DbConnectionPoolGroup poolGroup) SqlClientEventSource.Metrics.ExitActiveConnectionPoolGroup(); } - protected virtual DbConnectionInternal CreateConnection( - DbConnectionOptions options, - DbConnectionPoolKey poolKey, - DbConnectionPoolGroupProviderInfo poolGroupProviderInfo, - IDbConnectionPool pool, - DbConnection owningConnection, - DbConnectionOptions userOptions) - { - return CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection); - } - protected abstract DbConnectionInternal CreateConnection( DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionPoolGroupProviderInfo poolGroupProviderInfo, IDbConnectionPool pool, - DbConnection owningConnection); + DbConnection owningConnection, + DbConnectionOptions userOptions); abstract protected DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionData.stub.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionData.stub.cs new file mode 100644 index 0000000000..8911f38626 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionData.stub.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// @TODO: This is only a stub class for removing clearing errors while merging other files. + +namespace Microsoft.Data.SqlClient +{ + internal class SessionData + { + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.stub.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.stub.cs index 90e4eaabf6..d888c2e637 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.stub.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.stub.cs @@ -5,23 +5,31 @@ // @TODO: This is only a stub class for clearing errors while merging other files. using System; -using System.Data; +using System.Data.Common; using System.Threading.Tasks; +using Microsoft.Data.Common.ConnectionString; +using Microsoft.Data.ProviderBase; +using Microsoft.Data.SqlClient.ConnectionPool; using Microsoft.SqlServer.Server; namespace Microsoft.Data.SqlClient { - public class SqlConnection + public class SqlConnection : DbConnection { + internal bool _applyTransientFaultHandling = false; internal Task _currentReconnectionTask = null; + internal SessionData _recoverySessionData = null; #region Constructors + internal SqlConnection() {} internal SqlConnection(string connectionString) {} + #endregion #region Properties + internal Guid ClientConnectionId { get; set; } #if NETFRAMEWORK @@ -30,28 +38,32 @@ internal SqlConnection(string connectionString) {} internal bool HasLocalTransaction { get; set; } + internal DbConnectionInternal InnerConnection { get; set; } + internal bool Is2008OrNewer { get; set; } + internal int ObjectID { get; set; } + internal TdsParser Parser { get; set; } - internal ConnectionState State { get; set; } + internal DbConnectionPoolGroup PoolGroup { get; set; } internal SqlStatistics Statistics { get; set; } internal bool StatisticsEnabled { get; set; } + + internal DbConnectionOptions UserConnectionOptions { get; set; } + #endregion #region Methods + internal void Abort(Exception e) { } - internal void AddWeakReference(object value, int tag) - { - } + internal void AddWeakReference(object value, int tag) { } internal SqlTransaction BeginTransaction() => null; - - internal void Dispose() { } internal byte[] GetBytes(object o, out Format format, out int maxSize) { @@ -61,11 +73,18 @@ internal byte[] GetBytes(object o, out Format format, out int maxSize) } internal SqlInternalConnectionTds GetOpenTdsConnection() => null; - - internal void Open() { } + internal void PermissionDemand() { } + internal Task RegisterForConnectionCloseNotification(Task outerTask, object value, int tag) => Task.FromResult(default); + + internal void SetInnerConnectionEvent(DbConnectionInternal to) { } + + internal bool SetInnerConnectionFrom(DbConnectionInternal to, DbConnectionInternal from) => + false; + + internal void SetInnerConnectionTo(DbConnectionInternal to) { } internal void ValidateConnectionForExecute(string method, SqlCommand command) { } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs similarity index 86% rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs index 368742a8dd..ae4c7bc98d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs @@ -6,25 +6,29 @@ using System.Data.Common; using System.Diagnostics; using System.IO; +using System.Reflection; using Microsoft.Data.Common; using Microsoft.Data.Common.ConnectionString; using Microsoft.Data.ProviderBase; using Microsoft.Data.SqlClient.ConnectionPool; +#if NET +using System.Runtime.Loader; +#endif + namespace Microsoft.Data.SqlClient { - sealed internal partial class SqlConnectionFactory : DbConnectionFactory + sealed internal class SqlConnectionFactory : DbConnectionFactory { - - private const string _metaDataXml = "MetaDataXml"; - + public static readonly SqlConnectionFactory SingletonInstance = new SqlConnectionFactory(); + private SqlConnectionFactory() : base() { + #if NET SubscribeToAssemblyLoadContextUnload(); + #endif } - public static readonly SqlConnectionFactory SingletonInstance = new SqlConnectionFactory(); - override public DbProviderFactory ProviderFactory { get @@ -32,17 +36,7 @@ override public DbProviderFactory ProviderFactory return SqlClientFactory.Instance; } } - - protected override DbConnectionInternal CreateConnection( - DbConnectionOptions options, - DbConnectionPoolKey poolKey, - DbConnectionPoolGroupProviderInfo poolGroupProviderInfo, - IDbConnectionPool pool, - DbConnection owningConnection) - { - return CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection, userOptions: null); - } - + protected override DbConnectionInternal CreateConnection( DbConnectionOptions options, DbConnectionPoolKey poolKey, @@ -55,7 +49,7 @@ protected override DbConnectionInternal CreateConnection( SqlConnectionPoolKey key = (SqlConnectionPoolKey)poolKey; SessionData recoverySessionData = null; - SqlConnection sqlOwningConnection = (SqlConnection)owningConnection; + SqlConnection sqlOwningConnection = owningConnection as SqlConnection; bool applyTransientFaultHandling = sqlOwningConnection?._applyTransientFaultHandling ?? false; SqlConnectionString userOpt = null; @@ -76,9 +70,10 @@ protected override DbConnectionInternal CreateConnection( bool redirectedUserInstance = false; DbConnectionPoolIdentity identity = null; - // Pass DbConnectionPoolIdentity to SqlInternalConnectionTds if using integrated security. + // Pass DbConnectionPoolIdentity to SqlInternalConnectionTds if using integrated security + // or active directory integrated security. // Used by notifications. - if (opt.IntegratedSecurity) + if (opt.IntegratedSecurity || opt.Authentication is SqlAuthenticationMethod.ActiveDirectoryIntegrated) { if (pool != null) { @@ -148,6 +143,7 @@ protected override DbConnectionInternal CreateConnection( opt = new SqlConnectionString(opt, instanceName, userInstance: false, setEnlistValue: null); poolGroupProviderInfo = null; // null so we do not pass to constructor below... } + return new SqlInternalConnectionTds( identity, opt, @@ -171,7 +167,7 @@ protected override DbConnectionOptions CreateConnectionOptions(string connection return result; } - override internal DbConnectionPoolProviderInfo CreateConnectionPoolProviderInfo(DbConnectionOptions connectionOptions) + internal override DbConnectionPoolProviderInfo CreateConnectionPoolProviderInfo(DbConnectionOptions connectionOptions) { DbConnectionPoolProviderInfo providerInfo = null; @@ -183,7 +179,7 @@ override internal DbConnectionPoolProviderInfo CreateConnectionPoolProviderInfo( return providerInfo; } - override protected DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions(DbConnectionOptions connectionOptions) + protected override DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions(DbConnectionOptions connectionOptions) { SqlConnectionString opt = (SqlConnectionString)connectionOptions; @@ -193,7 +189,7 @@ override protected DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions { // never pool context connections. int connectionTimeout = opt.ConnectTimeout; - if ((0 < connectionTimeout) && (connectionTimeout < int.MaxValue / 1000)) + if (connectionTimeout > 0 && connectionTimeout < int.MaxValue / 1000) { connectionTimeout *= 1000; } @@ -201,8 +197,9 @@ override protected DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions { connectionTimeout = int.MaxValue; } - - if (opt.Authentication == SqlAuthenticationMethod.ActiveDirectoryInteractive || opt.Authentication == SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow) + + if (opt.Authentication is SqlAuthenticationMethod.ActiveDirectoryInteractive + or SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow) { // interactive/device code flow mode will always have pool's CreateTimeout = 10 x ConnectTimeout. if (connectionTimeout >= Int32.MaxValue / 10) @@ -215,24 +212,24 @@ override protected DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions } SqlClientEventSource.Log.TryTraceEvent("SqlConnectionFactory.CreateConnectionPoolGroupOptions | Set connection pool CreateTimeout '{0}' when Authentication mode '{1}' is used.", connectionTimeout, opt.Authentication); } + poolingOptions = new DbConnectionPoolGroupOptions( - opt.IntegratedSecurity, - opt.MinPoolSize, - opt.MaxPoolSize, - connectionTimeout, - opt.LoadBalanceTimeout, - opt.Enlist); + opt.IntegratedSecurity || opt.Authentication is SqlAuthenticationMethod.ActiveDirectoryIntegrated, + opt.MinPoolSize, + opt.MaxPoolSize, + connectionTimeout, + opt.LoadBalanceTimeout, + opt.Enlist); } return poolingOptions; } - - override internal DbConnectionPoolGroupProviderInfo CreateConnectionPoolGroupProviderInfo(DbConnectionOptions connectionOptions) + internal override DbConnectionPoolGroupProviderInfo CreateConnectionPoolGroupProviderInfo( + DbConnectionOptions connectionOptions) { return new SqlConnectionPoolGroupProviderInfo((SqlConnectionString)connectionOptions); } - internal static SqlConnectionString FindSqlConnectionOptions(SqlConnectionPoolKey key) { SqlConnectionString connectionOptions = (SqlConnectionString)SingletonInstance.FindConnectionOptions(key); @@ -247,7 +244,7 @@ internal static SqlConnectionString FindSqlConnectionOptions(SqlConnectionPoolKe return connectionOptions; } - + // @TODO: All these methods seem redundant ... shouldn't we always have a SqlConnection? override internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnection connection) { SqlConnection c = (connection as SqlConnection); @@ -338,6 +335,7 @@ protected override DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal internalConnection.ServerVersion); } + #if NET private void Unload(object sender, EventArgs e) { try @@ -350,7 +348,17 @@ private void Unload(object sender, EventArgs e) } } - partial void SubscribeToAssemblyLoadContextUnload(); + private void SqlConnectionFactoryAssemblyLoadContext_Unloading(AssemblyLoadContext obj) + { + Unload(obj, EventArgs.Empty); + } + + private void SubscribeToAssemblyLoadContextUnload() + { + AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading += + SqlConnectionFactoryAssemblyLoadContext_Unloading; + } + #endif } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.stub.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.stub.cs index 27fc1bc3fb..1cc6d14ec6 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.stub.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.stub.cs @@ -4,17 +4,42 @@ // @TODO: This is only a stub class for clearing errors while merging other files. +using System; +using System.Security; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Data.SqlClient.ConnectionPool; + namespace Microsoft.Data.SqlClient { internal class SqlInternalConnectionTds { internal SyncAsyncLock _parserLock = null; - - internal bool ThreadHasParserLockForClose { get; set; } - internal void DoomThisConnection() + internal SqlInternalConnectionTds( + DbConnectionPoolIdentity identity, + SqlConnectionString connectionOptions, + SqlCredential credential, + object providerInfo, + string newPassword, + SecureString newSecurePassword, + bool redirectedUserInterface, + SqlConnectionString userConnectionOptions = null, + SessionData reconnectSessionData = null, + bool applyTransientFaultHandling = false, + string accessToken = null, + IDbConnectionPool pool = null, + Func> accessTokenCallback = null) { } + + internal string InstanceName => null; + + internal bool ThreadHasParserLockForClose { get; set; } + + internal void Dispose() { } + + internal void DoomThisConnection() { } internal class SyncAsyncLock {