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및 DbConnectioninplements뿐만 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);
}
}
}
이 모든 도움을 바랍니다.