Microsoft.AspNetCore.All:v2.0.3 | ダッパー:v1.50.2
ベストプラクティスを正しく使用しているかどうかはわかりませんが、複数の接続文字列を処理するために、この方法で使用しています。
接続文字列が1つしかない場合は簡単です
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>();
}
}
}
DiagramRepository.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);
}
}
}
複数の接続文字列がある場合の問題
をDapper
利用するためIDbConnection
、さまざまなデータベース接続を区別する方法を考える必要があります。
IDbConnection
さまざまなデータベース接続に対応する「継承」された複数のインターフェイスを作成し、にさまざまSqlConnection
なデータベース接続文字列を挿入しようとしましたStartup
。
からSqlConnection
継承しDbConnection
、クラスDbConnection
だけでIDbConnection
なくComponent
クラスも補完するため、失敗しました。そのため、カスタムインターフェイスはSqlConnection
実装だけを使用することはできません。
また、DbConnection
異なる接続文字列を使用する独自のクラスを作成しようとしました。DbConnection
クラスからすべてのメソッドを実装する必要があるため、これは複雑すぎます。あなたはからの助けを失いましたSqlConnection
。
私がやることになること
- の間に
Startup
、すべての接続文字列値を辞書にロードしました。また、enum
マジックストリングを回避するために、すべてのデータベース接続名に対してを作成しました。
- 辞書をシングルトンとして挿入しました。
- を注入する代わりに、すべてのリポジトリの一時的なものとして
IDbConnection
作成IDbConnectionFactory
して注入しました。現在、すべてのリポジトリがIDbConnectionFactory
代わりに使用しますIDbConnection
ます。
- いつ正しい接続を選ぶべきですか?すべてのリポジトリのコンストラクタで!物事をきれいにするために、リポジトリの基本クラスを作成し、リポジトリに基本クラスから継承させました。正しい接続文字列の選択は、基本クラスで行うことができます。
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-私自身のファクトリ実装
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>();
}
}
}
DiagramRepository.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);
}
}
}
次に、他の接続と通信する必要がある他のリポジトリについて、それらの別のリポジトリ基本クラスを作成できます。
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);
}
}
}
これらすべての助けを願っています。