首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >连接池w/依赖项注入是否使用HTTP请求范围?

连接池w/依赖项注入是否使用HTTP请求范围?
EN

Stack Overflow用户
提问于 2012-03-09 21:04:48
回答 1查看 1.8K关注 0票数 2

注意:我不打算使用实体框架,因为它不支持异步查询。

对于下面的依赖注入和SQL连接池场景,我无法确定哪种方法更好。Server连接池(ADO.NET) MSDN文章建议使用using (sqlConn),因为我不会在启用连接池的情况下对connection.Open()connection.Close()进行攻击。

技术1:

  • 向我的SqlConnection类中注入一个CustomerRepository依赖项。
  • SqlConnection使用每个HTTP请求的实例。
  • 在将connection.Open()注入到CustomerRepository类之前调用它。

技术2:

  • 只将连接字符串注入我的CustomerRepository类。
  • 在每个CRUD方法中初始化using (SqlConnection)块?

其他需要考虑的事情

  1. 我将在我的SqlCommand.BeginExecuteReader()中使用异步调用来执行一些需要2-4秒的查询。
  2. 在某些特殊情况下,我还需要运行2个或更多并行SQL查询调用。
  3. 还请记住这两种技术如何影响IDisposableusing (connection)的编码风格。

问题

  1. 在启用连接池的情况下,这两种方法之间有什么区别吗?
  2. 我应该使用哪种技术?为什么?

技术1的代码示例:

代码语言:javascript
复制
// ------------------------------------------------------------
// 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的代码示例:

代码语言:javascript
复制
// ------------------------------------------------------------
// 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
            }
        }
    }
}

预先感谢您的周到投入:-)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-09 23:05:00

不要使用技术1。为完整的请求保留连接是不建议的:它应该尽快关闭,所以不要为完整的请求打开它。

不要使用技术2,在每个存储库中注入一个连接字符串是很麻烦的,如果要这样做,在我看来,您在代码中缺少了一个抽象。您可能不希望每个存储库都自己创建一个新的SqlConnection。

最好将某种类型的IDatabase抽象注入到存储库中。可以在IDatabase实现中注入连接字符串。这个抽象可以有一个BeginExecuteReader方法,或者甚至更高级的抽象。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9640972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档