Skip to content

Instantly share code, notes, and snippets.

@tracker1
Last active May 2, 2025 20:08
Show Gist options
  • Save tracker1/503b1584dec0fa432e31495b97edbf0c to your computer and use it in GitHub Desktop.
Save tracker1/503b1584dec0fa432e31495b97edbf0c to your computer and use it in GitHub Desktop.
Multiple Databases with C# and ASP.Net Scopes
using System.Collections.Concurrent;
using System.Data;
using Microsoft.Data.SqlClient;
public class DatabaseConnections : IDisposable {
public IDbConnection? FirstConnection { get { return getSqlConnection("First"); } }
public IDbConnection? SecondConnection { get { return getSqlConnection("Second"); } }
private IConfiguration config {get;set;}
private ConcurrentDictionary<string, IDbConnection> Connections = new ConcurrentDictionary<string, IDbConnection>();
public DatabaseConnections(IConfiguration config) {
this.config = config;
}
~DatabaseConnections() {
this.Dispose();
}
private IDbConnection? getSqlConnection(string name) {
IDbConnection? cn;
if (this.Connections.TryGetValue(name, out cn)) {
return cn;
}
var cs = this.config.GetConnectionString(name);
if (string.IsNullOrWhiteSpace(cs)) {
return null;
}
try {
var csb = new SqlConnectionStringBuilder(cs);
// TODO: configure for allowed cert chain
csb.TrustServerCertificate = true;
cn = new SqlConnection(csb.ConnectionString);
this.Connections.TryAdd(name, cn);
return cn;
} catch(Exception) {
return null;
}
}
public void Dispose()
{
var keys = this.Connections.Keys;
foreach (var key in keys) {
IDbConnection? cn;
if (Connections.Remove(key, out cn)) {
cn.Dispose();
}
}
}
}
public static class DatabaseConnectionsExtensions {
public static void AddDatabaseConnections(this IServiceCollection services)
{
services.AddScoped(o => {
var config = o.GetService<IConfiguration>();
if (config is null) throw new ApplicationException("Missing configuration.");
return new DatabaseConnections(config);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment