diff --git a/src/Microsoft.Data.SqlClient.slnx b/src/Microsoft.Data.SqlClient.slnx
index 9c03addd51..54863d7191 100644
--- a/src/Microsoft.Data.SqlClient.slnx
+++ b/src/Microsoft.Data.SqlClient.slnx
@@ -175,6 +175,10 @@
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryLogicLoader.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryLogicLoader.cs
index df556a49ba..a9340cd1b3 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryLogicLoader.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryLogicLoader.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.
@@ -357,28 +357,30 @@ internal sealed class AssemblyResolutionSubscription : IDisposable
{
#if NET
private bool _isSubscribed;
+ private readonly AssemblyLoadContext _currentAssemblyLoadContext;
#endif
internal AssemblyResolutionSubscription(bool subscribe)
{
- #if NET
+ #if NET
if (subscribe)
{
- AssemblyLoadContext.Default.Resolving += Default_Resolving;
+ _currentAssemblyLoadContext = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly());
+ _currentAssemblyLoadContext?.Resolving += Default_Resolving;
_isSubscribed = true;
}
- #endif
+ #endif
}
public void Dispose()
{
- #if NET
+ #if NET
if (_isSubscribed)
{
- AssemblyLoadContext.Default.Resolving -= Default_Resolving;
+ _currentAssemblyLoadContext?.Resolving -= Default_Resolving;
_isSubscribed = false;
}
- #endif
+ #endif
}
}
@@ -399,10 +401,11 @@ private static Assembly AssemblyResolver(AssemblyName arg)
string methodName = nameof(AssemblyResolver);
string fullPath = MakeFullPath(ProbingDirectory, arg.Name);
+ AssemblyLoadContext currentAlc = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly());
SqlClientEventSource.Log.TryTraceEvent(" Looking for '{2}' assembly by '{3}' full path."
, TypeName, methodName, arg, fullPath);
- return fullPath == null ? null : AssemblyLoadContext.Default.LoadFromAssemblyPath(fullPath);
+ return fullPath != null && currentAlc != null ? currentAlc.LoadFromAssemblyPath(fullPath) : null;
}
///
@@ -411,8 +414,8 @@ private static Assembly AssemblyResolver(AssemblyName arg)
///
/// This handler is only subscribed while a configured retry logic provider is being
/// resolved and constructed, and only when a custom retry logic type has been configured.
- /// It must not remain subscribed to after that,
- /// because doing so changes assembly resolution behavior for the entire application.
+ /// It must not remain subscribed to the calling after that,
+ /// because doing so can change assembly resolution behavior for the entire application.
///
private static Assembly Default_Resolving(AssemblyLoadContext arg1, AssemblyName arg2)
{
@@ -426,8 +429,8 @@ private static Assembly Default_Resolving(AssemblyLoadContext arg1, AssemblyName
}
///
- /// Performs a case-sensitive search to resolve the specified type name
- /// and its related assemblies in default assembly load context if they aren't loaded yet.
+ /// Performs a case-sensitive search to resolve the specified type name and its related
+ /// assemblies in the calling assembly load context if they aren't loaded yet.
///
/// Resolved type if it could resolve the type; otherwise, the `SqlConfigurableRetryFactory` type.
private static Type LoadType(string fullyQualifiedName)
diff --git a/src/Microsoft.Data.SqlClient/tests/Common/ConfigurableRetryLogic/RetryLogicConfigs.cs b/src/Microsoft.Data.SqlClient/tests/Common/ConfigurableRetryLogic/RetryLogicConfigs.cs
new file mode 100644
index 0000000000..650a6d2acc
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/Common/ConfigurableRetryLogic/RetryLogicConfigs.cs
@@ -0,0 +1,53 @@
+// 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.
+
+namespace Microsoft.Data.SqlClient.Tests.Common.ConfigurableRetryLogic;
+
+///
+/// Transport object for retry logic configuration parameters. This is used to pass
+/// values which would ordinarily be part of the SqlConfigurableRetryLogicConnection
+/// or SqlConfigurableRetryLogicCommand section to
+///
+public sealed class RetryLogicConfigs
+{
+ ///
+ /// Equivalent of the deltaTime value in an app.config file.
+ ///
+ public TimeSpan DeltaTime { get; set; }
+
+ ///
+ /// Equivalent of the maxTime value in an app.config file.
+ ///
+ public TimeSpan MaxTimeInterval { get; set; }
+
+ ///
+ /// Equivalent of the minTime value in an app.config file.
+ ///
+ public TimeSpan MinTimeInterval { get; set; }
+
+ ///
+ /// Equivalent of the numberOfTries value in an app.config file.
+ ///
+ public int NumberOfTries { get; set; }
+
+ ///
+ /// Equivalent of the transientErrors value in an app.config file.
+ ///
+ public string? TransientErrors { get; set; }
+
+ ///
+ /// Equivalent of the authorizedSqlCondition value in an app.config file.
+ ///
+ public string? AuthorizedSqlCondition { get; set; }
+
+ ///
+ /// Equivalent of the retryLogicType value in an app.config file.
+ ///
+ public string? RetryLogicType { get; set; }
+
+ ///
+ /// Equivalent of the retryMethod value in an app.config file.
+ ///
+ public string? RetryMethodName { get; set; }
+}
diff --git a/src/Microsoft.Data.SqlClient/tests/Common/ConfigurableRetryLogic/RetryLogicLoaderHelper.cs b/src/Microsoft.Data.SqlClient/tests/Common/ConfigurableRetryLogic/RetryLogicLoaderHelper.cs
new file mode 100644
index 0000000000..b439aa3385
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/Common/ConfigurableRetryLogic/RetryLogicLoaderHelper.cs
@@ -0,0 +1,128 @@
+// 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.Reflection;
+
+namespace Microsoft.Data.SqlClient.Tests.Common.ConfigurableRetryLogic;
+
+///
+/// Contains helper methods for creating and configuring instances of
+/// SqlConfigurableRetryLogicLoader and its associated configuration objects without needing
+/// to populate an app.config file.
+///
+public static class RetryLogicLoaderHelper
+{
+ private const string ConfigurationLoaderTypeName = "Microsoft.Data.SqlClient.SqlConfigurableRetryLogicLoader";
+ private const string InterfaceCnnCfgTypeName = "Microsoft.Data.SqlClient.ISqlConfigurableRetryConnectionSection";
+ private const string InterfaceCmdCfgTypeName = "Microsoft.Data.SqlClient.ISqlConfigurableRetryCommandSection";
+ private const string CnnCfgTypeName = "Microsoft.Data.SqlClient.SqlConfigurableRetryConnectionSection";
+ private const string CmdCfgTypeName = "Microsoft.Data.SqlClient.SqlConfigurableRetryCommandSection";
+ private const string DefaultTransientErrors = "1204, 1205, 1222, 49918, 49919, 49920, 4060, 4221, 40143, 40613, 40501, 40540, 40197, 42108, 42109, 10929, 10928, 10060, 10054, 10053, 997, 233, 64, 20, 0, -2, 207, 102, 2812";
+
+ private static readonly Random s_random = new();
+
+ private static readonly Assembly s_sqlClientAssembly = typeof(SqlConnection).Assembly;
+ private static readonly Type s_configurationLoaderType = s_sqlClientAssembly.GetType(ConfigurationLoaderTypeName)!;
+ private static readonly Type s_interfaceCnnCfgType = s_sqlClientAssembly.GetType(InterfaceCnnCfgTypeName)!;
+ private static readonly Type s_interfaceCmdCfgType = s_sqlClientAssembly.GetType(InterfaceCmdCfgTypeName)!;
+ private static readonly Type s_cnnCfgType = s_sqlClientAssembly.GetType(CnnCfgTypeName)!;
+ private static readonly Type s_cmdCfgType = s_sqlClientAssembly.GetType(CmdCfgTypeName)!;
+
+ private static readonly Type[] s_cfgLoaderParamsType =
+ [
+ s_interfaceCnnCfgType,
+ s_interfaceCmdCfgType,
+ typeof(string), typeof(string)
+ ];
+ private static readonly ConstructorInfo s_loaderCtorInfo = s_configurationLoaderType.GetConstructor(s_cfgLoaderParamsType)!;
+
+ ///
+ /// Creates and returns an instance of SqlConfigurableRetryLogicLoader with the specified
+ /// connection and command retry logic configurations.
+ ///
+ /// The configuration for the connection retry logic.
+ /// The configuration for the command retry logic.
+ /// The created loader instance.
+ public static object CreateLoader(RetryLogicConfigs cnnConfig, RetryLogicConfigs cmdConfig)
+ {
+ object cnnCfgObj = Activator.CreateInstance(s_cnnCfgType)!;
+ SetValue(cnnCfgObj, s_cnnCfgType, "DeltaTime", cnnConfig.DeltaTime);
+ SetValue(cnnCfgObj, s_cnnCfgType, "MinTimeInterval", cnnConfig.MinTimeInterval);
+ SetValue(cnnCfgObj, s_cnnCfgType, "MaxTimeInterval", cnnConfig.MaxTimeInterval);
+ SetValue(cnnCfgObj, s_cnnCfgType, "NumberOfTries", cnnConfig.NumberOfTries);
+ SetValue(cnnCfgObj, s_cnnCfgType, "AuthorizedSqlCondition", cnnConfig.AuthorizedSqlCondition);
+ SetValue(cnnCfgObj, s_cnnCfgType, "TransientErrors", cnnConfig.TransientErrors);
+ SetValue(cnnCfgObj, s_cnnCfgType, "RetryLogicType", cnnConfig.RetryLogicType);
+ SetValue(cnnCfgObj, s_cnnCfgType, "RetryMethod", cnnConfig.RetryMethodName);
+
+ object cmdCfgObj = Activator.CreateInstance(s_cmdCfgType)!;
+ SetValue(cmdCfgObj, s_cmdCfgType, "DeltaTime", cmdConfig.DeltaTime);
+ SetValue(cmdCfgObj, s_cmdCfgType, "MinTimeInterval", cmdConfig.MinTimeInterval);
+ SetValue(cmdCfgObj, s_cmdCfgType, "MaxTimeInterval", cmdConfig.MaxTimeInterval);
+ SetValue(cmdCfgObj, s_cmdCfgType, "NumberOfTries", cmdConfig.NumberOfTries);
+ SetValue(cmdCfgObj, s_cmdCfgType, "AuthorizedSqlCondition", cmdConfig.AuthorizedSqlCondition);
+ SetValue(cmdCfgObj, s_cmdCfgType, "TransientErrors", cmdConfig.TransientErrors);
+ SetValue(cmdCfgObj, s_cmdCfgType, "RetryLogicType", cmdConfig.RetryLogicType);
+ SetValue(cmdCfgObj, s_cmdCfgType, "RetryMethod", cmdConfig.RetryMethodName);
+
+ return s_loaderCtorInfo.Invoke([cnnCfgObj, cmdCfgObj, default!, default!]);
+ }
+
+ ///
+ /// Creates and returns an instance of SqlConfigurableRetryLogicLoader with the specified
+ /// connection and command retry logic configurations, and also retrieves the associated
+ /// connection and command providers.
+ ///
+ /// The configuration for the connection retry logic.
+ /// The configuration for the command retry logic.
+ /// When this method returns, contains the connection provider.
+ /// When this method returns, contains the command provider.
+ /// The created loader instance.
+ public static object ReturnLoaderAndProviders(RetryLogicConfigs cnnCfg, RetryLogicConfigs cmdCfg, out SqlRetryLogicBaseProvider cnnProvider, out SqlRetryLogicBaseProvider cmdProvider)
+ {
+ object loaderObj = CreateLoader(cnnCfg, cmdCfg);
+
+ cnnProvider = GetValue(loaderObj, s_configurationLoaderType, "ConnectionProvider");
+ cmdProvider = GetValue(loaderObj, s_configurationLoaderType, "CommandProvider");
+ return loaderObj;
+ }
+
+ ///
+ /// Creates a RetryLogicConfigs object with random values for its properties, optionally specifying
+ /// default values for certain mandatory properties.
+ ///
+ /// The retry method to use.
+ /// The authorized SQL condition.
+ /// The transient errors.
+ /// The created retry logic configuration.
+ public static RetryLogicConfigs CreateRandomConfig(string? method, string? authorizedSqlCondition = null, string transientErrors = DefaultTransientErrors)
+ {
+ TimeSpan start = TimeSpan.Zero;
+ TimeSpan end = TimeSpan.FromSeconds(60);
+ TimeSpan min = GenerateTimeSpan(start, end);
+
+ return new RetryLogicConfigs()
+ {
+ DeltaTime = GenerateTimeSpan(start, end),
+ MinTimeInterval = min,
+ MaxTimeInterval = GenerateTimeSpan(min, end),
+ NumberOfTries = s_random.Next(1, 60),
+ AuthorizedSqlCondition = authorizedSqlCondition,
+ TransientErrors = transientErrors,
+ RetryMethodName = method
+ };
+ }
+
+ private static T GetValue(object obj, Type type, string propName, BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) =>
+ (T)type.GetProperty(propName, flags)?.GetValue(obj)!;
+
+ private static void SetValue(object obj, Type type, string propName, T value, BindingFlags flags = BindingFlags.Public | BindingFlags.Instance) =>
+ type.GetProperty(propName, flags)?.SetValue(obj, value);
+
+ private static TimeSpan GenerateTimeSpan(TimeSpan start, TimeSpan end)
+ {
+ int max = (int)(end - start).TotalSeconds;
+ return start.Add(TimeSpan.FromSeconds(s_random.Next(max)));
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConfigurableRetryLogicTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConfigurableRetryLogicTest.cs
index b24a32e804..450135f440 100644
--- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConfigurableRetryLogicTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConfigurableRetryLogicTest.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.
@@ -86,11 +86,10 @@ public void ValidateRetryParameters()
#if NET
///
/// Regression test: triggering the configurable retry logic loader through its normal
- /// entry points must not leave a process-wide
- /// resolving handler
- /// installed. Such a handler participates in resolution of every assembly the host
- /// application fails to find, and serves them out of this component's probing directory,
- /// which can load code from an unintended location.
+ /// entry points must not leave a resolving handler subscribed to the current
+ /// . Such a handler participates
+ /// in resolution of every assembly the host application fails to find, and serves them
+ /// out of this component's probing directory, which can load code from an unintended location.
///
[Fact]
public void RetryLogicProviderDoesNotLeaveAssemblyProbingEnabled()
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTests.csproj
index 5fbfeb94c2..5fe219a71d 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTests.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTests.csproj
@@ -103,6 +103,7 @@
+
@@ -134,6 +135,7 @@
+
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs
index bd6e551890..89bb478fe0 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.
@@ -6,21 +6,12 @@
using System.Collections.Generic;
using System.Reflection;
using Xunit;
+using Microsoft.Data.SqlClient.Tests.Common.ConfigurableRetryLogic;
namespace Microsoft.Data.SqlClient.ManualTesting.Tests
{
public class RetryLogicConfigHelper
{
- private const string ConfigurationLoaderTypeName = "Microsoft.Data.SqlClient.SqlConfigurableRetryLogicLoader";
- private const string AppContextSwitchManagerTypeName = "Microsoft.Data.SqlClient.SqlAppContextSwitchManager";
- private const string ApplyContextSwitchesMethodName = "ApplyContextSwitches";
- private const string InterfaceCnnCfgTypeName = "Microsoft.Data.SqlClient.ISqlConfigurableRetryConnectionSection";
- private const string InterfaceCmdCfgTypeName = "Microsoft.Data.SqlClient.ISqlConfigurableRetryCommandSection";
-
- private const string CnnCfgTypeName = "Microsoft.Data.SqlClient.SqlConfigurableRetryConnectionSection";
- private const string CmdCfgTypeName = "Microsoft.Data.SqlClient.SqlConfigurableRetryCommandSection";
- private const string AppCtxCfgTypeName = "Microsoft.Data.SqlClient.AppContextSwitchOverridesSection";
-
public const string RetryMethodName_Fix = "CreateFixedRetryProvider";
public const string RetryMethodName_Inc = "CreateIncrementalRetryProvider";
public const string RetryMethodName_Exp = "CreateExponentialRetryProvider";
@@ -31,79 +22,21 @@ public class RetryLogicConfigHelper
private const string CreateExceptionMethodName = "CreateException";
private const string AddMethodName = "Add";
- public const string DefaultTransientErrors = "1204, 1205, 1222, 49918, 49919, 49920, 4060, 4221, 40143, 40613, 40501, 40540, 40197, 42108, 42109, 10929, 10928, 10060, 10054, 10053, 997, 233, 64, 20, 0, -2, 207, 102, 2812";
-
private static readonly Random s_random = new Random();
private static readonly Assembly s_sqlClientAssembly = typeof(SqlConnection).Assembly;
- private static readonly Type s_appContextSwitchManagerType = s_sqlClientAssembly.GetType(AppContextSwitchManagerTypeName);
private static readonly Type s_sqlretrylogicType = s_sqlClientAssembly.GetType(SqlRetryLogicTypeName);
- private static readonly Type s_configurationLoaderType = s_sqlClientAssembly.GetType(ConfigurationLoaderTypeName);
private static readonly Type s_sqlErrorType = typeof(SqlError);
private static readonly Type s_sqlErrorCollectionType = typeof(SqlErrorCollection);
- private static readonly Type[] s_cfgLoaderParamsType = new Type[]
- {
- s_sqlClientAssembly.GetType(InterfaceCnnCfgTypeName),
- s_sqlClientAssembly.GetType(InterfaceCmdCfgTypeName),
- typeof(string), typeof(string)
- };
private static readonly Type[] s_sqlErrorParamsType = new Type[]
{
typeof(int), typeof(byte), typeof(byte),
typeof(string), typeof(string), typeof(string),
typeof(int), typeof(Exception)
};
- private static readonly ConstructorInfo s_loaderCtorInfo = s_configurationLoaderType.GetConstructor(s_cfgLoaderParamsType);
private static readonly ConstructorInfo s_sqlErrorCtorInfo = s_sqlErrorType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, s_sqlErrorParamsType, null);
private static readonly ConstructorInfo s_sqlErrorCollectionCtorInfo = s_sqlErrorCollectionType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
- public static object CreateLoader(RetryLogicConfigs cnnConfig, RetryLogicConfigs cmdConfig)
- {
- var cnnCfgType = s_sqlClientAssembly.GetType(CnnCfgTypeName);
- var cnnCfgObj = Activator.CreateInstance(cnnCfgType);
- SetValue(cnnCfgObj, cnnCfgType, "DeltaTime", cnnConfig.DeltaTime);
- SetValue(cnnCfgObj, cnnCfgType, "MinTimeInterval", cnnConfig.MinTimeInterval);
- SetValue(cnnCfgObj, cnnCfgType, "MaxTimeInterval", cnnConfig.MaxTimeInterval);
- SetValue(cnnCfgObj, cnnCfgType, "NumberOfTries", cnnConfig.NumberOfTries);
- SetValue(cnnCfgObj, cnnCfgType, "AuthorizedSqlCondition", cnnConfig.AuthorizedSqlCondition);
- SetValue(cnnCfgObj, cnnCfgType, "TransientErrors", cnnConfig.TransientErrors);
- SetValue(cnnCfgObj, cnnCfgType, "RetryLogicType", cnnConfig.RetryLogicType);
- SetValue(cnnCfgObj, cnnCfgType, "RetryMethod", cnnConfig.RetryMethodName);
-
- var cmdCfgType = s_sqlClientAssembly.GetType(CmdCfgTypeName);
- var cmdCfgObj = Activator.CreateInstance(cmdCfgType);
- SetValue(cmdCfgObj, cmdCfgType, "DeltaTime", cmdConfig.DeltaTime);
- SetValue(cmdCfgObj, cmdCfgType, "MinTimeInterval", cmdConfig.MinTimeInterval);
- SetValue(cmdCfgObj, cmdCfgType, "MaxTimeInterval", cmdConfig.MaxTimeInterval);
- SetValue(cmdCfgObj, cmdCfgType, "NumberOfTries", cmdConfig.NumberOfTries);
- SetValue(cmdCfgObj, cmdCfgType, "AuthorizedSqlCondition", cmdConfig.AuthorizedSqlCondition);
- SetValue(cmdCfgObj, cmdCfgType, "TransientErrors", cmdConfig.TransientErrors);
- SetValue(cmdCfgObj, cmdCfgType, "RetryLogicType", cmdConfig.RetryLogicType);
- SetValue(cmdCfgObj, cmdCfgType, "RetryMethod", cmdConfig.RetryMethodName);
-
- return s_loaderCtorInfo.Invoke(new object[] { cnnCfgObj, cmdCfgObj, default, default });
- }
-
- public static void ApplyContextSwitchByManager(string name, bool value)
- {
-#if !NETFRAMEWORK
- var appCtxType = s_sqlClientAssembly.GetType(AppCtxCfgTypeName);
- var appCtxObj = Activator.CreateInstance(appCtxType);
- SetValue(appCtxObj, appCtxType, "Value", string.Concat(name, "=", value));
-
- var method = s_appContextSwitchManagerType.GetMethod(ApplyContextSwitchesMethodName, BindingFlags.Static | BindingFlags.NonPublic);
- method.Invoke(null, new object[] { appCtxObj });
-#else
- AppContext.SetSwitch(name, value);
-#endif
- }
-
- public static SqlRetryLogicBaseProvider GetConnectionProvider(object loader)
- => GetValue(loader, s_configurationLoaderType, "ConnectionProvider");
-
- public static SqlRetryLogicBaseProvider GetCommandProvider(object loader)
- => GetValue(loader, s_configurationLoaderType, "CommandProvider");
-
public static void AssessProvider(SqlRetryLogicBaseProvider provider, RetryLogicConfigs option)
=> AssessRetryLogic(provider.RetryLogic, option);
@@ -150,33 +83,6 @@ public static IEnumerable