注入连接字符串与 IDbConnection

Posted

技术标签:

【中文标题】注入连接字符串与 IDbConnection【英文标题】:Injecting connection strings vs IDbConnection 【发布时间】:2012-08-20 17:45:11 【问题描述】:

注入连接字符串与IDbConnection 实例的权衡是什么?

我使用 StructureMap 将各种服务注入到我的 ASP.NET MVC 应用程序中,其中大部分都需要数据库访问以进行 LINQ-to-SQL 查询。注入 IDbConnection 似乎比通用连接 string 参数更可测试且更容易为 IoC 配置,但我担心如果我没有明确地将连接包装在 @ 987654323@块。

我应该注意哪些连接池的优点或缺点?

注入的连接字符串

using (var con = new SqlConnection(InjectedConnectionString))

    con.Execute("INSERT INTO Logs (...) VALUES (...)");
    using (var db = new MyDataContext(con))
    
        var records = from p in db.Products
                      select p;
    

注入的 IDbConnection

con.Execute("INSERT INTO Logs (...) VALUES (...)");
using (var db = new MyDataContext(InjectedConnection))

    var records = from p in db.Products
                  select p;

【问题讨论】:

为什么要关注打开的连接?您正在使用 using 块,它确保连接将始终关闭。 @David,只有当我注入连接字符串并明确使用using 时。注入IDbConnection 时,我没有,这是差异的一部分。我会在我的问题中说得更清楚。 啊,我明白了。在注入的 IDbConnection 情况下,DataContext 不会处理您的连接(如果它从连接字符串本身创建连接,它只会处理连接),因此这是您的责任。但是连接池的连接很便宜,所以我个人会注入连接字符串并避免连接重用(除非您使用的数据库系统不使用池)。 【参考方案1】:

任何中等复杂的 IoC 容器(结构图)的一个特征是对象的being able to control the lifetimes。默认情况下,结构映射使用瞬态生命周期。这意味着它为每个对象图创建一个新实例。在实践中,这通常与 per-web-request 相同(除非您在代码中使用 container.GetInstance<T>())。

通过使用结构映射注入数据库连接等宝贵资源,您可以控制它们的生存时间。单个资源可以(如果您选择)在整个 Web 请求中重复使用,或者为每次使用重新创建。

此外,这些选择(以及配置)现在已外部化到注册表中,而不是通过您的代码散布它们。如果您必须更改连接的创建方式,您只需查看一处。具有单一职责的类总是首选。

就您的连接池而言,任何 IoC 容器都不会涉及连接池等细节。然而,它们确实对生命有帮助。 Structuremap 将在任何IDisposable 对象上调用Dispose()(嗯,实际上是调用它的解释器)。

编辑:同样在连接池中,每个生命周期都有自己的规则,用于处理对象的方式和时间。 Transient 依赖 CLR 来处理,但是 HttpRequestScoped 在每个请求结束时确定性地处理对象。使用HttpRequestScoped 会阻止您最大化连接数。

【讨论】:

如果 StructureMap 注入了多个 IDbConnection 实例(不确定是否/何时),如果没有及时处理,连接池是否会达到最大值? 我不是连接池或 Linq-to-SQL 方面的专家,但请参阅我的最新编辑 谢谢,凯洛蒂。对于 Web 应用程序,HybridHttpOrThreadLocalScoped 是否等同于 HttpRequestScoped 事后的想法 - 除非您跨 Web 请求共享连接,否则您无法真正防止连接池最大化。但是使用HttpRequestScope 会通过确定性地处理连接来减少这种可能性。 有点,名字说明了一切。在生产中,是的,它们是等价的。在单元测试中,它将使用ThreadLocal,因为没有 HTTP 上下文。

以上是关于注入连接字符串与 IDbConnection的主要内容,如果未能解决你的问题,请参考以下文章

005.连接式与断开式查询

.Net 核心依赖注入 IdbConnection

SQL 注入 - 如果我们将多个预定义字符串与用户值连接起来

牛掰!从sql注入到连接3389只需这几步

牛掰!从sql注入到连接3389只需这几步

Python 3.5 与 2.7 之间字​​符串连接的巨大时间差异