我对 .NET 有深入的了解,但最近一直在使用 Python 和 Ruby。我发现自己在思考如何在 Ruby 中最好地为需要它们的对象提供依赖性。
起初,我并不认为 DI 和 IoC 框架需要与依赖项交互,因为动态语言(la redefinition、mixins、stubs 等)的宽松性。然而,后来我找到了关于为什么在动态语言中 不需要 DI/IoC 框架的答案。所提供的理由不太适合我。我希望我能看到一个可能会澄清问题的示例。
我有点不同意的推荐意见:
原因 1:可以在运行时更改依赖类(考虑测试)
在Why are IOC containers unnecessary with dynamic languages我们看到依赖类(非注入(inject)),比如 X
,可以在测试中被 stub 或模拟。当然可以,但这需要我们知道我们的 System Under Test
依赖于名为 X
的东西。如果我们的 System Under Test
突然依赖于 N
而不是 X
,我们现在必须记住模拟 N
而不是X
。使用 DI 的好处是我们永远不会不小心运行带有生产依赖项的测试,因为我们总是会传递模拟的依赖项。
原因2:子类化或使用构造函数注入(inject)进行测试
在每个人最喜欢的所有 DI + Ruby 的 goto 资源中,LEGOs, Play-Doh, and Programming ,我们看到了一个将被测系统子类化以模拟依赖项的示例。或者,我们可以使用构造函数注入(inject)。好的,所以 B
依赖于 A
。我们调用 B.get_dependency
为 B
提供 A
的实例。但是如果 A
依赖于 N
而 N
又依赖于 X
呢?我们必须对链中的每个连续对象调用 get_dependency
吗?
原因3:依赖可以混入或者monkeypatched
Fabio mentions我们可以只使用 mixins/monkeypatch。所以 X
混入了 N
。但问题是,如果 X
依赖于 A
,而 A
又依赖于 B
怎么办?我们是否只对链下的每个依赖项使用 mixin?我知道它是如何工作的,但它很快就会变得困惑和困惑。
旁注:Many users say动态语言不需要 DI 框架。然而,Angular.JS 确实受益于实现一个非常可靠的 DI 系统。 Angular 建立在 JavaScript 之上,这是一种动态语言。这种方法可以与 Ruby 或 Python 相媲美吗?
请记住,我并不是说我想强制将 DI/IoC 引入 Ruby、Python 等。
最佳答案
虽然许多人认为不需要 DI,但我同意你的看法,它确实非常需要;但有时它会与 Python 提供的其他技术混合使用。我建议你看看venusian ,它可能有点冗长,但如果你来自 .NET,你就会看到这种关系。一句话:venusian 允许你在不改变它们行为的情况下注释你的方法。因此,您可以编写 venusian 装饰器,这样您的单元测试就不会受到影响。 Pyramid例如,使用 venusian 来注释 View 。
关于python - 动态语言中依赖注入(inject)的真实示例是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13877777/