【问题标题】:IoC and .NET frameworkIoC 和 .NET 框架
【发布时间】:2011-04-07 20:24:09
【问题描述】:

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

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

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

【问题讨论】:

    标签: c# .net ioc-container


    【解决方案1】:

    代码维护不仅仅是将一个提供程序换成另一个提供程序。对我来说,依赖注入更多的是保持代码在逻辑上分离,因此更易于维护,而不是在提供程序更改时对代码进行未来验证。

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

    也就是说,我从未使用过 IOC 容器,也从未见过需要一个,因此我无法就问题的这方面发表评论。

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

    【讨论】:

    • 嗯,你让我在“DI 更多的是关于解耦,而不是关于让你的供应商面向未来。”太糟糕了,您没有更多的 DI 经验可提供。但无论如何 +1。
    【解决方案2】:

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

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

    最好是从低级别的 ADO.NET DbConnection API 迁移到 O/RM,例如 LINQ to SQL 或实体框架。然后你通常会有一个LinqToSqlUserRepository

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

    【讨论】:

    • 我知道存储库和 orm 的 :) 我刚刚写了一个非常简单的用法示例 :) 还是谢谢
    • +1 表示“注入 SqlConnection 或 IDbConnection 将毫无用处,因为 DbConnection 是一个泄漏的抽象”非常正确。
    • 各位,泄漏抽象是什么意思?
    • @Davita:你试过谷歌搜索吗?维基百科(当然)有定义:en.wikipedia.org/wiki/Leaky_abstraction.
    【解决方案3】:

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

    除了 IOC 和类似的东西,我实际上已经多次使用 DbFactoryProvider (some more info) 来创建我的 Connections 和其他 DB 相关对象,并通过 ConnectionString 读取提供程序。

    DB 的主要问题是通常您不能真正仅将 ANSI-SQL 与数据库一起使用,因此当您与具体类分离时,您的 sql 是不可传输的。 (即 MySql 中的限制或 Sql Server 中的 Over 和 Partition)。

    关于 DI/IOC 和其他与 DB 无关的东西,解耦你的类和删除依赖关系非常好,并且在单元测试时很有帮助,比如当你有一个你正在使用的服务时即使不在单元中也很有帮助测试,当您针对一项服务而另一个团队仍在开发该服务时,您可以创建一个假服务,基本上解决您的问题(不是全部),这样您就可以在真正的服务可用之前针对某些东西进行工作。

    还有更多示例,但针对服务(数据库存储库/Web/授权/其他)工作是第一个最直接的附加值。

    【讨论】:

      【解决方案4】:

      IOC 在那里,尽管您想在现实中使用一种类型的提供程序,但总有一天会发生一些变化,您可能需要一个辅助适配器,因此最好使用 IoC 而不是使用 new 关键字创建对象。随着时间的推移(随着需求的变化),IoC 可以灵活地改变事物。

      【讨论】:

      • 好吧,如果有一天我想使用另一种类型,我认为 MEF 更适合此目的。如我错了请纠正我。在这种具体情况下使用 IoC 不会通过松散耦合代码来提高代码质量吗?
      • 是的,这就是它灵活的原因......我没有说任何反对你的说法,我也没有公开支持它,但这并不意味着我说的是错误的......
      • 我不得不强烈反对并说 IOC 存在这样您就可以按照单一责任原则将功能分解成更小的部分,并通过他们的合同来表示这些功能(接口),而不会给实例化和提供更多的小组件(这是 IOC 处理的部分)造成很大的负担。
      【解决方案5】:

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

      我还应该提到,使用 IoC 并仅向接口编写代码将使单元测试更加容易。在处理数据库连接时尤其如此。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多