internal static string GetSafeName(string name) => SqlDistributedLock.GetSafeName(name);
 /// <summary>
 /// Constructs a new lock using the provided <paramref name="name"/>.
 ///
 /// The provided <paramref name="transaction"/> will be used to connect to the database and will provide lock scope. It is assumed to be externally managed and
 /// will not be committed or rolled back.
 ///
 /// Unless <paramref name="exactName"/> is specified, <paramref name="name"/> will be escaped/hashed to ensure name validity.
 /// </summary>
 public SqlDistributedReaderWriterLock(string name, IDbTransaction transaction, bool exactName = false)
     : this(name, exactName, n => SqlDistributedLock.CreateInternalLock(n, transaction))
 {
 }
 /// <summary>
 /// Constructs a new lock using the provided <paramref name="name"/>.
 ///
 /// The provided <paramref name="connectionString"/> will be used to connect to the database.
 ///
 /// Unless <paramref name="exactName"/> is specified, <paramref name="name"/> will be escaped/hashed to ensure name validity.
 /// </summary>
 public SqlDistributedReaderWriterLock(string name, string connectionString, Action <SqlConnectionOptionsBuilder>?options = null, bool exactName = false)
     : this(name, exactName, n => SqlDistributedLock.CreateInternalLock(n, connectionString, options))
 {
 }
 /// <summary>
 /// Creates a semaphore with name <paramref name="name"/> that can be acquired up to <paramref name="maxCount"/>
 /// times concurrently. When acquired, the semaphore will be scoped to the given <paramref name="transaction"/>.
 /// The <paramref name="transaction"/> and its <see cref="IDbTransaction.Connection"/> are assumed to be externally managed:
 /// the <see cref="SqlDistributedSemaphore"/> will not attempt to open, close, commit, roll back, or dispose them
 /// </summary>
 public SqlDistributedSemaphore(string name, int maxCount, IDbTransaction transaction)
     : this(name, maxCount, n => SqlDistributedLock.CreateInternalLock(n, transaction))
 {
 }
 /// <summary>
 /// Creates a semaphore with name <paramref name="name"/> that can be acquired up to <paramref name="maxCount"/>
 /// times concurrently. When acquired, the semaphore will be scoped to the given <paramref name="connection"/>.
 /// The <paramref name="connection"/> is assumed to be externally managed: the <see cref="SqlDistributedSemaphore"/> will
 /// not attempt to open, close, or dispose it
 /// </summary>
 public SqlDistributedSemaphore(string name, int maxCount, IDbConnection connection)
     : this(name, maxCount, n => SqlDistributedLock.CreateInternalLock(n, connection))
 {
 }
 /// <summary>
 /// Creates a semaphore with name <paramref name="name"/> that can be acquired up to <paramref name="maxCount"/>
 /// times concurrently. The provided <paramref name="connectionString"/> will be used to connect to the database.
 /// </summary>
 public SqlDistributedSemaphore(string name, int maxCount, string connectionString, Action <SqlConnectionOptionsBuilder>?options = null)
     : this(name, maxCount, n => SqlDistributedLock.CreateInternalLock(n, connectionString, options))
 {
 }