Microsoft.AspNetCore.All : v2.0.3 | Dapper : v1.50.2
모범 사례를 올바르게 사용하고 있는지 확실하지 않지만 여러 연결 문자열 을 처리하기 위해 이렇게하고 있습니다.
연결 문자열이 하나만 있으면 쉽습니다.
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);
}
}
}
연결 문자열이 두 개 이상인 경우 문제
를 Dapper
활용 하므로 IDbConnection
서로 다른 데이터베이스 연결을 구별하는 방법을 생각해야합니다.
IDbConnection
다른 데이터베이스 연결에 해당하는 에서 '상속'된 여러 인터페이스를 만들고 SqlConnection
에 다른 데이터베이스 연결 문자열을 삽입 하려고 했습니다 Startup
.
실패 때문 SqlConnection
로부터 상속 DbConnection
및 DbConnection
inplements뿐만 IDbConnection
아니라 Component
클래스입니다. 따라서 사용자 정의 인터페이스는 표현만을 사용할 수 없습니다 SqlConnection
.
또한 DbConnection
다른 연결 문자열 을 사용하는 자체 클래스 를 만들려고했습니다 . DbConnection
클래스의 모든 메서드를 구현해야하므로 너무 복잡합니다 . 에서 도움을 잃었습니다 SqlConnection
.
내가하는 일
- 동안
Startup
모든 연결 문자열 값을 사전에로드했습니다. 또한 enum
매직 문자열을 피하기 위해 모든 데이터베이스 연결 이름에 대해을 만들었습니다 .
- 사전을 Singleton으로 삽입했습니다.
- 주입하는 대신 모든 저장소에 대해 Transient를
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>();
}
}
}
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);
}
}
}
그런 다음 다른 연결과 통신해야하는 다른 저장소에 대해 다른 저장소 기본 클래스를 만들 수 있습니다.
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);
}
}
}
이 모든 도움을 바랍니다.