IoC和.NET框架

4

我想知道在处理.NET时,使用IoC模式的最佳实践是什么。

例如,我应该通过IoC容器创建SqlConnection/OracleConnection或其他任何提供程序,还是应该使用简单的new关键字?

将我的类与具体提供程序类型分开是否有任何价值(包括当我只想使用一种类型的提供程序时)?

5个回答

2

代码维护不仅仅是替换一个提供者。对我来说,依赖注入更多地是为了保持代码逻辑上的分离,从而使其更易于维护,而不是为了未来某个提供者更改时保证代码兼容性。

DI还可以更轻松地将一个项目中的代码重用到另一个项目中,因为它使各部分之间的依赖关系更加明确。

话虽如此,我从未使用过IOC容器,也从未看到需要使用它,因此无法对这个问题进行评论。

但是,您应该尽可能地从代码中删除隐式依赖项,以保持代码的可重用性、可维护性和正确性。


好的,"DI更多地是关于解耦而不是未来证明你的提供者"这句话就已经让我被吸引了。很遗憾你没有更多的DI经验可以分享,但还是点个赞。 - Robert Harvey

1

注入SqlConnectionIDbConnection是相当无用的,因为DbConnection是一个泄漏的抽象。你只能用它来调用存储过程或简单的SELECT * FROM VIEW类型的查询。任何更复杂的查询都将根据SQL方言而异。

当将连接本身隐藏在更高级别的抽象后面时,例如IUserRepository或某种类型,您将有更好的成功机会。该接口的默认实现可能是与MS SQL Server通信的SqlUserRepository,或者是与Oracle通信的OracleUserRepository

更好的方法是远离低级别的ADO.NET DbConnection API,转向诸如LINQ to SQL或Entity Framework之类的O/RM。然后,您通常会拥有一个LinqToSqlUserRepository

请注意,在这种情况下,我仍在谈论XXXUserRepository。接口仍然没有改变。换句话说:IUserRepository不是一个泄漏的抽象。您可以替换此接口进行单元测试,而使用SqlConnection几乎不可能。


我知道仓库和ORM :) 我刚刚写了一个非常简单的使用示例 :) 无论如何,谢谢。 - Davita
“注入一个 SqlConnection 或 IDbConnection 是相当无用的,因为 DbConnection 是一个泄漏的抽象层。”非常正确。 - quentin-starin
各位,leaky abstraction 是什么意思? - Davita
@Davita:你试过谷歌搜索吗?维基百科当然有定义:http://en.wikipedia.org/wiki/Leaky_abstraction。 - Steven

0

控制反转(IoC)的存在是为了在现实中,尽管您想使用一种类型的提供程序,但有一天某些事情会发生变化,您可能需要一个次要适配器,因此最好使用IoC而不是使用new关键字创建对象。随着时间的推移(随着需求的变化),IoC提供了灵活性来改变事物。


如果我将来想使用另一种类型,我认为MEF更适合这个目的。如果我错了,请纠正我。在这种具体情况下使用IoC是否通过松散耦合代码提高了代码质量? - Davita
是的,这就是为什么它很灵活...我并没有反对你的说法,也没有公开支持它,但这并不能说明我的话是错的... - Numenor
我必须强烈反对并说,控制反转(IOC)的存在是为了将功能分解为更小的部分,遵循单一职责原则,并通过它们的契约(接口)表示这些功能部分,而不会创建大量实例化和提供这些更多的小组件的负担(这就是IOC处理的部分)。 - quentin-starin

0

即使是.NET类,使用IoC也是一个好的实践。这将允许您的代码仅与接口或基类绑定(如果可用)。不仅如此,您还可以使用IoC框架指定构造函数参数。这对于SqlConnection中的连接字符串可能非常有用。

我还应该提到,使用IoC并仅编写接口代码将使单元测试变得更加容易。特别是在处理DB连接时,这一点尤为真实。


0

如果您使用IDbConnection和所有其他类而不是具体类,则在单元测试中它可能具有价值。

除了IOC等内容之外,我实际上已经多次使用DbFactoryProvider更多信息)创建连接和其他与数据库相关的对象,并通过ConnectionString读取提供程序。

与数据库相关的主要问题通常是您无法仅使用ANSI-SQL与数据库,因此尽管您与具体类分离,但sql并不可传输。 (例如,在MySql中限制或在Sql Server中的Over和Partition)。

关于DI / IOC以及其他与DB无关的内容,将类解耦并消除依赖项非常有用,并在单元测试时有所帮助,例如当您正在针对服务工作时。即使不在单元测试中,当您正在针对服务工作且另一个团队仍在开发服务时,也可以创建一个虚假的服务来解决您的问题(不是全部),以便您可以在真正的服务可用之前进行工作。

还有很多例子,但是与服务(数据库存储库/网络/授权/任何其他)对抗是最直接的增值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接