【问题标题】:Question on DI and how to solve some problems关于DI的问题以及如何解决一些问题
【发布时间】:2011-07-23 01:56:27
【问题描述】:

我是依赖注入的新手。我从来没有使用过,也从来没有完全理解过它到底是什么,但是在我最后一次攻击这个话题之后,我发现这是一种解耦对象及其依赖项的方法,一旦它们不负责实例化它的具体版本不再依赖,因为现在容器会为我们做这件事,并将准备好的对象交付到我们手中。

现在重点是; “我什么时候应该使用它?”,总是???实际上,由于我是新手,甚至从未见过使用这种模式的项目,我无法理解我应该如何将它应用到我的域对象!在我看来,我将永远不会实例化我的对象,并且容器将始终为我做这件事,但随之而来的是一些疑问......

1) 例如,部分依赖来自 UI 的对象呢?

public class User(String name, IValidator validator)

假设我从 UI 中获取用户名,那么容器如何知道它并仍然为我提供这个对象?

2) 我还面临其他情况;如果一个依赖现在是一个已经实例化的对象,比如说......一个 SINGLETON 对象,例如。我看到了关于注入的依赖项的生命范围的设置(我在谈论 Spring.NET,例如 http 请求范围)...但是,请求和其他与 web 相关的东西在我的表示层,那么我如何在不违反任何设计规则的情况下链接我的表示层和我的域层(因为我的域应该完全不知道它在哪里被使用,不具有层依赖性等)

我很想听听大家的意见。非常感谢。

【问题讨论】:

  • 今天有很多 DI 问题 =) 看看这个答案是否有帮助。 :stackoverflow.com/questions/5433211/…
  • 它很有用@giddy,谢谢,但不是重点! =)
  • @Renato 只是认为这有助于解释为什么使用 DI。 =)
  • @giddy 确实对我的朋友有帮助!我已阅读并赞成您的回答,这对我来说是完全清楚的。发生的事情是我已经得到了你在那里解释的内容,所以我想我的疑问是这个问题更进一步。谢谢小伙伴的关心!欣赏!

标签: c# oop dependency-injection spring.net domain-model


【解决方案1】:

一般来说,一旦您使用 IoC,您往往希望将所有内容都注册到 IoC 并让容器吐出完全水合的对象。但是,您提出了一些有效的观点。

也许“依赖”的定义是有序的;从最广泛的意义上讲,依赖关系只是一组功能(接口),给定类需要具体实现才能使类正常工作。因此,大多数重要的程序都充满了依赖关系。为了便于维护,通常首选所有依赖项的松散耦合。但是,即使松耦合,如果这些对象需要您不想污染 IoC 注册表的专门信息,您也不需要自动实例化依赖项。目标是松散耦合使用,而不一定是创建。

关于第 1 点,一些 IoC 框架在提供外部参数方面表现不佳。但是,您通常可以将委托注册为工厂方法。该委托可能属于一个对象,例如由 UI 提供外部信息的控制器。登录就是一个完美的例子:创建一个对象,比如一个 LoginController,并将它注册到 IoC 作为你的 ILoginController。您将在登录页面上引用该控制器,它会在登录页面被实例化时被注入,并且登录页面会将输入的凭据传递给它。然后,控制器将执行身份验证,并将具有生成用户对象的方法 GetAuthenticatedUser()。您可以在 IoC 中将此方法注册为用户的工厂,并且每当需要用户时,工厂委托将被评估,或者将批发传递给依赖方法,该方法将在真正需要用户时调用它。

关于第 2 点,设置对象的单个实例是 IoC 模式的优势。无需使用私有实例构造函数、静态实例和静态构造函数来创建一个真正的单例来生成实例,您只需向 IoC 注册该类并告诉它只实例化一次并将该实例用于所有请求。力量就是柔韧性;如果您以后希望有多个实例,则只需更改注册即可。无论哪种方式,您都不会破坏任何设计模式规则;视图将始终注入一个控制器,无论该控制器对于所有页面都是相同的还是每个请求的新实例。

【讨论】:

    【解决方案2】:

    1) 这个构造器可能不适合使用,可能是您将验证器注入到错误的位置/方式。

    2)较新的View、Model和Controller都应该知道有一个IoC,它应该位于后台架构中(实际上是MVC组件实例化的地方)

    当您觉得架构可能变得复杂并且必须由许多人维护时,您应该使用 IoC。如果您正在编写企业应用程序,或者您认为可以使用插件扩展的 UI,那么您可能需要它,如果您正在编写命令行实用程序,则可能不需要。

    【讨论】:

      【解决方案3】:

      只要您想获得以下任何好处,就应该使用依赖注入:

      • 轻松更换模块的能力
      • 在应用程序的各个部分或不同应用程序之间重用模块的能力
      • 当您想要进行并行开发时,因为系统的组件依赖于抽象,所以可以独立并行地开发它们
      • 当您因为松散耦合而想要更轻松地维护系统时
      • 当您需要可测试性(替换模块的专业化)时。这是使用 DI 的最大原因之一

      回答您的其他问题:

      1) 您可以配置许多 IoC 容器,以便可以指定某些构造函数参数,而其他参数则由容器解析。但是,您可能需要考虑重构那段代码,因为 UserFactory 可能更合适,它采用验证器依赖项,并且有一个 NewUser 方法接受用户名并返回一个新用户(或者实例化它直接或从容器中解析)。

      2) 您构建的每个应用程序都将有一个组合根,您的容器在其中配置,并且根对象被解析。因此,每个应用程序都有自己的 IoC 配置,因此应用程序类型和配置设置之间存在预期的联系。任何常见的抽象注册都可以放在所有应用程序之间共享的配置代码中。

      【讨论】:

        猜你喜欢
        • 2011-07-29
        • 2018-05-24
        • 2021-12-30
        • 1970-01-01
        • 2015-06-03
        • 1970-01-01
        • 1970-01-01
        • 2018-02-08
        • 1970-01-01
        相关资源
        最近更新 更多