Microsoft.AspNetCore.All : v2.0.3 | Dapper : v1.50.2
Ich bin nicht sicher, ob ich die Best Practices richtig verwende oder nicht, aber ich mache es auf diese Weise, um mehrere Verbindungszeichenfolgen zu verarbeiten .
Es ist einfach, wenn Sie nur 1 Verbindungszeichenfolge haben
Startup.cs
using System.Data;
using System.Data.SqlClient;
namespace DL.SO.Project.Web.UI
{
public class Startup
{
public IConfiguration Configuration { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
string dbConnectionString = this.Configuration.GetConnectionString("dbConnection1");
services.AddTransient<IDbConnection>((sp) => new SqlConnection(dbConnectionString));
services.AddScoped<IDiameterRepository, DiameterRepository>();
}
}
}
DiameterRepository.cs
using Dapper;
using System.Data;
namespace DL.SO.Project.Persistence.Dapper.Repositories
{
public class DiameterRepository : IDiameterRepository
{
private readonly IDbConnection _dbConnection;
public DiameterRepository(IDbConnection dbConnection)
{
_dbConnection = dbConnection;
}
public IEnumerable<Diameter> GetAll()
{
const string sql = @"SELECT * FROM TABLE";
return _dbConnection.Query<Diameter>(sql);
}
}
}
Probleme, wenn Sie mehr als eine Verbindungszeichenfolge haben
Da Dapper
verwendet wird IDbConnection
, müssen Sie sich eine Möglichkeit überlegen , verschiedene Datenbankverbindungen zu unterscheiden.
Ich habe versucht, mehrere Schnittstellen zu erstellen, die von IDbConnection
verschiedenen Datenbankverbindungen "geerbt" wurden , und SqlConnection
verschiedene Datenbankverbindungszeichenfolgen einzuschalten Startup
.
Das ist fehlgeschlagen, weil SqlConnection
erbt von DbConnection
und DbConnection
implementiert nicht nur, IDbConnection
sondern auch Component
Klasse. Ihre benutzerdefinierten Schnittstellen können also nicht nur die SqlConnection
Implenentation verwenden.
Ich habe auch versucht, eine eigene DbConnection
Klasse zu erstellen , die eine andere Verbindungszeichenfolge verwendet. Das ist zu kompliziert, weil Sie alle Methoden aus der DbConnection
Klasse implementieren müssen . Du hast die Hilfe von verloren SqlConnection
.
Was ich am Ende mache
- Währenddessen habe
Startup
ich alle Verbindungszeichenfolgenwerte in ein Wörterbuch geladen. Ich habe auch einen Namen enum
für alle Datenbankverbindungen erstellt, um magische Zeichenfolgen zu vermeiden.
- Ich habe das Wörterbuch als Singleton injiziert.
- Anstatt zu injizieren
IDbConnection
, habe ich IDbConnectionFactory
das als Transient für alle Repositorys erstellt und injiziert. Jetzt nehmen alle Repositories IDbConnectionFactory
statt IDbConnection
.
- Wann wählen Sie die richtige Verbindung? Im Konstruktor aller Repositories! Um die Dinge sauber zu machen, habe ich Repository-Basisklassen erstellt und die Repositorys von den Basisklassen erben lassen. Die richtige Auswahl der Verbindungszeichenfolge kann in den Basisklassen erfolgen.
DatabaseConnectionName.cs
namespace DL.SO.Project.Domain.Repositories
{
public enum DatabaseConnectionName
{
Connection1,
Connection2
}
}
IDbConnectionFactory.cs
using System.Data;
namespace DL.SO.Project.Domain.Repositories
{
public interface IDbConnectionFactory
{
IDbConnection CreateDbConnection(DatabaseConnectionName connectionName);
}
}
DapperDbConenctionFactory - meine eigene Factory-Implementierung
namespace DL.SO.Project.Persistence.Dapper
{
public class DapperDbConnectionFactory : IDbConnectionFactory
{
private readonly IDictionary<DatabaseConnectionName, string> _connectionDict;
public DapperDbConnectionFactory(IDictionary<DatabaseConnectionName, string> connectionDict)
{
_connectionDict = connectionDict;
}
public IDbConnection CreateDbConnection(DatabaseConnectionName connectionName)
{
string connectionString = null;
if (_connectDict.TryGetValue(connectionName, out connectionString))
{
return new SqlConnection(connectionString);
}
throw new ArgumentNullException();
}
}
}
Startup.cs
namespace DL.SO.Project.Web.UI
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
var connectionDict = new Dictionary<DatabaseConnectionName, string>
{
{ DatabaseConnectionName.Connection1, this.Configuration.GetConnectionString("dbConnection1") },
{ DatabaseConnectionName.Connection2, this.Configuration.GetConnectionString("dbConnection2") }
};
services.AddSingleton<IDictionary<DatabaseConnectionName, string>>(connectionDict);
services.AddTransient<IDbConnectionFactory, DapperDbConnectionFactory>();
services.AddScoped<IDiameterRepository, DiameterRepository>();
}
}
}
DiameterRepository.cs
using Dapper;
using System.Data;
namespace DL.SO.Project.Persistence.Dapper.Repositories
{
public class DiameterRepository : DbConnection1RepositoryBase, IDiameterRepository
{
public DiameterRepository(IDbConnectionFactory dbConnectionFactory)
: base(dbConnectionFactory) { }
public IEnumerable<Diameter> GetAll()
{
const string sql = @"SELECT * FROM TABLE";
return base.DbConnection.Query<Diameter>(sql);
}
}
}
DbConnection1RepositoryBase.cs
using System.Data;
using DL.SO.Project.Domain.Repositories;
namespace DL.SO.Project.Persistence.Dapper
{
public abstract class DbConnection1RepositoryBase
{
public IDbConnection DbConnection { get; private set; }
public DbConnection1RepositoryBase(IDbConnectionFactory dbConnectionFactory)
{
this.DbConnection = dbConnectionFactory.CreateDbConnection(DatabaseConnectionName.Connection1);
}
}
}
Für andere Repositorys, die mit den anderen Verbindungen kommunizieren müssen, können Sie dann eine andere Repository-Basisklasse für diese erstellen.
using System.Data;
using DL.SO.Project.Domain.Repositories;
namespace DL.SO.Project.Persistence.Dapper
{
public abstract class DbConnection2RepositoryBase
{
public IDbConnection DbConnection { get; private set; }
public DbConnection2RepositoryBase(IDbConnectionFactory dbConnectionFactory)
{
this.DbConnection = dbConnectionFactory.CreateDbConnection(DatabaseConnectionName.Connection2);
}
}
}
using Dapper;
using System.Data;
namespace DL.SO.Project.Persistence.Dapper.Repositories
{
public class ParameterRepository : DbConnection2RepositoryBase, IParameterRepository
{
public ParameterRepository (IDbConnectionFactory dbConnectionFactory)
: base(dbConnectionFactory) { }
public IEnumerable<Parameter> GetAll()
{
const string sql = @"SELECT * FROM TABLE";
return base.DbConnection.Query<Parameter>(sql);
}
}
}
Hoffe all diese Hilfe.