注意:我不打算使用实体框架,因为它不支持异步查询。
对于下面的依赖注入和SQL连接池场景,我无法确定哪种方法更好。Server连接池(ADO.NET) MSDN文章建议使用using (sqlConn),因为我不会在启用连接池的情况下对connection.Open()和connection.Close()进行攻击。
技术1:
SqlConnection类中注入一个CustomerRepository依赖项。SqlConnection使用每个HTTP请求的实例。connection.Open()注入到CustomerRepository类之前调用它。技术2:
CustomerRepository类。using (SqlConnection)块?其他需要考虑的事情
SqlCommand.BeginExecuteReader()中使用异步调用来执行一些需要2-4秒的查询。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
}
}
}
}预先感谢您的周到投入:-)
发布于 2012-03-09 23:05:00
不要使用技术1。为完整的请求保留连接是不建议的:它应该尽快关闭,所以不要为完整的请求打开它。
不要使用技术2,在每个存储库中注入一个连接字符串是很麻烦的,如果要这样做,在我看来,您在代码中缺少了一个抽象。您可能不希望每个存储库都自己创建一个新的SqlConnection。
最好将某种类型的IDatabase抽象注入到存储库中。可以在IDatabase实现中注入连接字符串。这个抽象可以有一个BeginExecuteReader方法,或者甚至更高级的抽象。
https://stackoverflow.com/questions/9640972
复制相似问题