Примечание: Я не планирую использовать Entity Framework, поскольку он НЕ поддерживает асинхронные запросы.
Я не могу понять, какой подход будет лучше для следующего сценария с внедрением зависимостей и пулами соединений SQL.
Пул подключений к SQL Server (ADO.NET) В статье MSDN рекомендуется использовать using (sqlConn)
, поскольку я не обращаю внимание на connection.Open()
и connection.Close()
при включенном пуле подключений.
Техника 1:
- Внедрить зависимость
SqlConnection
в мой класс CustomerRepository
.
- Использовать экземпляр для каждого HTTP-запроса для
SqlConnection
.
- Позвоните
connection.Open()
, прежде чем он будет введен в класс CustomerRepository.
Техника 2:
- Внедрить только строку подключения в мой
CustomerRepository
класс.
- Инициализировать
using (SqlConnection)
блоков в каждом из моих методов CRUD?
Дополнительные моменты, которые следует учитывать
- Я буду использовать асинхронные вызовы с моим
SqlCommand.BeginExecuteReader()
для некоторых запросов SQL, выполнение которых занимает около 2-4 секунд.
- В некоторых особых сценариях мне также нужно запускать 2 или более параллельных вызова SQL-запроса.
- Пожалуйста, имейте в виду, как эти две техники влияют на стиль кодирования для
IDisposable
и using (connection)
.
Вопросы
- Существуют ли различия между двумя подходами , учитывая, что Пул соединений включен ?
- Какую технику мне использовать и почему?
Пример кода для техники 1:
// ------------------------------------------------------------
// Autofac Dependency Injection setup
// ------------------------------------------------------------
ContainerBuilder builder = new ContainerBuilder();
builder.Register(
c => {
var conn = new SqlConnection( "connectionString" );
conn.Open(); // open the connection ahead of time before injecting it into my CustomerRepository
return conn;
})
.Named("myNamedConnection", typeof(SqlConnection))
.InstancePerHttpRequest();
builder.Register(
c => {
new CustomerRepository(c.ResolveNamed<SqlConnection>("myNamedConnection")))
})
.As<ICustomerRepository>();
// ------------------------------------------------------------
// CustomerRepository
// ------------------------------------------------------------
public class CustomerRepository : ICustomerRepository, IDisposable
{
private SqlConnection conn;
private bool disposed;
public CustomerRepository(SqlConnection connection)
{
conn = connection;
disposed = false;
}
public Customer GetById(int id)
{
using (var cmd = conn.CreateCommand())
{
// code to retrieve Customer by id
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
if (conn != null)
{
conn.Dispose();
conn = null;
}
}
disposed = true;
}
}
}
Пример кода для техники 2:
// ------------------------------------------------------------
// CustomerRepository
// ------------------------------------------------------------
public class CustomerRepository : ICustomerRepository
{
private readonly string strConn;
public CustomerRepository(string strConnection) // strConnection has Connection Pooling enabled
{
strConn = strConnection;
}
public Customer GetById(int id)
{
using (var conn = new SqlConnection(this.strConn))
{
using (var cmd = conn.CreateCommand())
{
// code to retrieve Customer by id
}
}
}
}
Заранее благодарим за любые вдумчивые замечания: -)