注入连接字符串与 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的主要内容,如果未能解决你的问题,请参考以下文章