69 lines
2.4 KiB
C#
69 lines
2.4 KiB
C#
using Microsoft.Data.SqlClient;
|
|
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace XLAB2.Infrastructure;
|
|
|
|
internal sealed class SqlServerConnectionFactory : IDatabaseConnectionFactory
|
|
{
|
|
private static readonly Lazy<IDatabaseConnectionFactory> CurrentFactory = new(() => new SqlServerConnectionFactory(DatabaseConfiguration.Current), LazyThreadSafetyMode.ExecutionAndPublication);
|
|
|
|
private readonly DatabaseOptions _options;
|
|
|
|
public SqlServerConnectionFactory(DatabaseOptions options)
|
|
{
|
|
_options = options ?? throw new ArgumentNullException(nameof(options));
|
|
ConnectionString = BuildConnectionString(options);
|
|
}
|
|
|
|
public static IDatabaseConnectionFactory Current => CurrentFactory.Value;
|
|
|
|
public string ConnectionString { get; }
|
|
|
|
public DatabaseOptions Options => _options;
|
|
|
|
public SqlConnection CreateConnection()
|
|
{
|
|
return new SqlConnection(ConnectionString);
|
|
}
|
|
|
|
public async Task<SqlConnection> OpenConnectionAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
var connection = CreateConnection();
|
|
|
|
try
|
|
{
|
|
await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
|
|
return connection;
|
|
}
|
|
catch
|
|
{
|
|
await connection.DisposeAsync().ConfigureAwait(false);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
internal static string BuildConnectionString(DatabaseOptions options)
|
|
{
|
|
var builder = new SqlConnectionStringBuilder
|
|
{
|
|
ApplicationName = string.IsNullOrWhiteSpace(options.ApplicationName) ? "XLAB2" : options.ApplicationName.Trim(),
|
|
ConnectRetryCount = Math.Max(0, options.ConnectRetryCount),
|
|
ConnectRetryInterval = Math.Max(1, options.ConnectRetryIntervalSeconds),
|
|
ConnectTimeout = Math.Max(1, options.ConnectTimeoutSeconds),
|
|
DataSource = options.Server.Trim(),
|
|
Encrypt = options.Encrypt,
|
|
InitialCatalog = options.Database.Trim(),
|
|
IntegratedSecurity = options.IntegratedSecurity,
|
|
MaxPoolSize = Math.Max(1, options.MaxPoolSize),
|
|
MinPoolSize = Math.Max(0, options.MinPoolSize),
|
|
MultipleActiveResultSets = options.MultipleActiveResultSets,
|
|
Pooling = options.Pooling,
|
|
TrustServerCertificate = options.TrustServerCertificate
|
|
};
|
|
|
|
return builder.ConnectionString;
|
|
}
|
|
}
|