Questions tagged «dependency-injection»

依赖注入是一种设计模式,其中通过构造函数,方法或字段(属性)设置组件的依赖关系(对象的实例,属性)。它是更一般的依赖项反转的一种特殊形式。

4
为什么我们需要依赖注入的框架?[关闭]
我一直在阅读有关控制反转原理和依赖注入作为其实现的更多信息,并且我确信我理解它。 似乎基本上是在说“不要在类中声明类成员的实例化”。相反,实例化应该通过构造函数传递并分配;从外部来源“注入”到班级中。 如果就这么简单(看起来如此),为什么我们需要像spring或guice这样的带有注释的框架?我在这里缺少基本的东西吗?我真的很难理解依赖注入框架的用途。 编辑:关于可能的重复,我相信我的问题更加独特,因为它询问的是一般的DI框架,而不仅仅是Spring。Spring不仅是一个DI框架,所以有很多人想要使用Spring的原因都与DI无关。

2
依赖注入多少钱?
我在一个项目中工作,该项目使用(Spring)依赖注入来处理实际上是类依赖的所有内容。我们现在已经将Spring配置文件增加到大约4000行。不久前,我观看了Bob叔叔在YouTube上的一次演讲(不幸的是,我找不到该链接),在该演讲中,他建议仅将几个中央依赖项(例如工厂,数据库等)注入到Main组件中,然后从它们分布。 这种方法的优点是将DI框架与应用程序的大部分解耦,并且还使Spring配置更干净,因为工厂将包含以前配置中的更多内容。相反,这将导致创建逻辑在许多工厂类之间传播,并且测试可能会变得更加困难。 因此,我的问题确实是,您会在一种或另一种方法中看到哪些其他优点或缺点?有没有最佳做法?非常感谢你的回答!

12
编写代码方法论的逐渐转变是否会影响系统性能?我应该在乎吗?
TD; DR: 关于我在问的问题有些困惑,所以这是问题背后的驱动思想: 我一直希望这个问题是什么。我本来可能说得不太好。但是其意图一直是“ 模块化,分离,松散耦合,解耦,重构的代码 ”,其本质明显比“ 整体式单一单元,在一个地方完成所有工作,一个文件,紧密耦合的 ”代码慢。剩下的只是我当时或现在或以后会遇到的细节和各种表现形式。在某种程度上,它肯定较慢。就像无碎片磁盘一样,您必须从任何地方拾起碎片。慢一点 当然。但是我应该在乎吗? 问题不在于... 与微优化,过早优化等无关。这与“优化这一部分或死亡”无关。 之后怎么样了? 它涉及随着时间而出现的有关编写代码的总体方法,技术和思考方式: “将此代码作为依赖项注入到您的类中” “每个班级写一个文件” “将视图与数据库,控制器,域分开”。 不要编写意大利面同质的单个代码块,而是编写可以协同工作的许多单独的模块化组件 它是关于在十年内当前在大多数框架中看到和倡导的代码的方式和样式,这些框架是在大会上倡导的,并且是通过社区传播的。这是思维方式从“整体块”到“微服务”的转变。随之而来的是机器级别的性能和开销,以及一些程序员级别的开销。 原始问题如下: 在计算机科学领域,我注意到编程方面的思维方式发生了显着变化。我经常遇到这样的建议: 编写较小的函数式代码(这种方式更具可测试性和可维护性) 将现有代码重构为越来越小的代码块,直到大多数方法/函数只有几行长并且很清楚它们的目的是什么(与更大的整体块相比,它创建了更多函数) 编写只做一件事的函数-关注点分离等(通常会在堆栈上创建更多函数和更多帧) 创建更多文件(每个文件一个类,用于分解目的的更多类,用于诸如MVC,域架构,设计模式,OO等层的目的,这会创建更多文件系统调用) 与“旧”或“过时”或“意大利面条”编码实践相比,这是一个变化,在常规编码实践中,您的方法跨越2500行,并且大型类和上帝对象可以完成所有工作。 我的问题是这样的: 当涉及到机器代码,1和0,汇编指令以及HDD盘片时,我应该完全担心我的类完全分离的OO代码以及各种重构的小型函数和方法也会生成额外的开销? 细节 尽管我对ASM到底如何处理OO代码及其方法调用以及DB调用和编译器调用如何转换为在HDD磁盘上移动执行器臂的方式并不太熟悉,但我确实有一些想法。我假设每个额外的函数调用,对象调用或“ #include”调用(在某些语言中)都会生成一组额外的指令,从而增加代码量并增加各种“代码接线”开销,而无需添加实际的“有用”代码。我还认为可以在ASM实际上在硬件上运行之前对其进行良好的优化,但是优化也只能做很多事情。 因此,我的问题是-与“包含一个大方法,其中包含一个大方法一切都放在一个整体文件中”,由于这种开销? 为清楚起见,更新: 我假设采用相同的代码并将其拆分,重构,解耦为越来越多的函数,对象以及方法和类将导致越来越多的参数在较小的代码段之间传递。因为可以肯定的是,重构代码必须保持线程运行,并且这需要传递参数。与单个整体类或方法相比,更多的方法,更多的类或更多的Factory Method设计模式导致传递更多信息位的开销更大。 有人说(引用待定),所有代码中多达70%是由ASM的MOV指令组成的-向CPU寄存器加载适当的变量,而不是进行实际的计算。就我而言,您可以使用PUSH / POP指令来加载CPU时间,以提供各种代码之间的链接和参数传递。您编写的代码段越小,所需的“链接”开销就越大。我担心这种联系会增加软件的膨胀和减慢速度,我想知道我是否应该关注这一点,以及是否要关注(如果有的话),因为现在和将来的下一代程序员都在为下个世纪构建软件,则必须使用和使用使用这些做法构建的软件。 更新:多个文件 我现在正在编写新代码,正在逐渐替换旧代码。特别是我注意到旧的类之一是〜3000行文件(如前所述)。现在,它已成为位于各个目录中的15-20个文件的集合,包括测试文件,不包括我用来将某些东西绑定在一起的PHP框架。还有更多文件。对于磁盘I / O,加载多个文件比加载一个大文件要慢。当然,并非所有文件都已加载,它们是根据需要加载的,并且存在磁盘缓存和内存缓存选项,但我仍然相信,这loading multiple files需要比loading a single file内存更多的处理工作。我将其添加到我的关注中。 更新:依赖注入所有内容 过一会儿再说。我认为我的问题被误解了。也许我选择误解了一些答案。我并不是在谈论微优化,因为一些答案已经被挑出来了(至少我认为我所说的关于微优化的说法是用词不当),而是整体上“重构代码以放松紧密耦合”的动向。 ,在代码的每个级别。我是最近从Zend Con来的,这种风格的代码一直是公约的核心和核心内容之一。从视图中解耦逻辑,从模型中解脱视图,从数据库中解脱模型,并且如果可能的话,从数据库中解耦数据。依赖-注入所有内容,有时意味着只添加什么都不做的接线代码(函数,类,样板),但可以用作接缝/勾点,在大多数情况下,很容易使代码大小加倍。 …

3
依赖注入如何增加耦合?
在有关依赖项注入的Wikipedia页面上,劣势部分告诉我们: 依赖注入通过要求子系统的用户满足该子系统的需求来增加耦合。 链接到反对依赖注入的文章。 依赖注入使类使用接口而不是具体的实现。那应该导致耦合减少,不是吗? 我想念什么?依赖注入如何增加类之间的耦合?

4
“控制反转”是否会促进“贫血领域模型”?
当我在上一个项目中使用IoC容器时,最终得到了贫乏的实体以及我在Stateless Services中的大部分业务逻辑。 我见过其他开发人员编写的利用“控制反转”的项目,并且它们始终是“贫血”。 由于“贫血域模型”是反模式,是否可以使用IoC和富域?他们有没有很好的例子,这样做的开源项目?

6
Spring应当自动装配哪些类(何时使用依赖注入)?
我已经在Spring中使用Dependency Injection已有一段时间了,我了解它的工作原理以及使用它的优缺点。但是,当我创建一个新类时,我常常想知道-该类是否应该由Spring IOC Container管理? 而且我不想谈论@Autowired注释,XML配置,setter注入,构造函数注入等之间的区别。我的问题是一个普遍的问题。 假设我们有一个带有Converter的服务: @Service public class Service { @Autowired private Repository repository; @Autowired private Converter converter; public List<CarDto> getAllCars() { List<Car> cars = repository.findAll(); return converter.mapToDto(cars); } } @Component public class Converter { public CarDto mapToDto(List<Car> cars) { return new ArrayList<CarDto>(); // do the mapping here } …

4
拦截与注入:框架架构决策
我正在帮助设计这个框架。使用某些通用组件应完成一些通用任务:特别是记录,缓存和引发事件。 我不确定是否最好使用依赖注入并将所有这些组件引入每个服务(例如属性),还是应该在每种服务方法上放置某种元数据并使用拦截来完成这些常见任务? 这是两个示例: 注射: public class MyService { public ILoggingService Logger { get; set; } public IEventBroker EventBroker { get; set; } public ICacheService Cache { get; set; } public void DoSomething() { Logger.Log(myMessage); EventBroker.Publish<EventType>(); Cache.Add(myObject); } } 这是另一个版本: 拦截: public class MyService { [Log("My message")] [PublishEvent(typeof(EventType))] public void DoSomething() …

5
使用NInject建立工厂的最佳方法是什么?
我对在MVC3中使用NInject进行依赖项注入非常满意。在MVC3应用程序中工作时,我使用NInject开发了一个自定义的Controller Creation Factory,因此所创建的任何控制器都将通过此Controller Factory注入依赖项。 现在,我开始开发Windows应用程序,我想使用应用程序范围依赖注入。即,必须通过NInject创建每个对象,以简化单元测试。请指导我确保创建的每个对象都只能通过NInject Factory。 例如,如果在Button_Click事件的任何Windows窗体上我都写: TestClass testClass = new TestClass() 并且TestClass有任何依赖,例如,ITest必须自动解决。我知道我可以使用: Ikernel kernel = new StandardKenel() //AddBinding() TestClass testClass = kenel.get<TestClass>(); 但是我发现每次要创建对象时都要执行此操作很麻烦。它还迫使开发人员以特定方式创建对象。可以做得更好吗? 我可以有一个用于对象创建的中央存储库,然后每个对象创建都会自动使用该存储库吗?

6
依赖注入; 减少样板代码的良好做法
我有一个简单的问题,我甚至不确定它是否有答案,但让我们尝试。我使用C ++进行编码,并使用依赖注入来避免全局状态。这工作得很好,而且我不会经常出现意外/未定义的行为。 但是我意识到,随着项目的发展,我正在编写许多我认为很简单的代码。更糟糕的是:事实上,比起实际的代码,样板代码更多,因此有时很难理解。 没有什么比一个好的例子更好了,让我们开始吧: 我有一个名为TimeFactory的类,它创建Time对象。 有关更多详细信息(不确定是否相关):时间对象非常复杂,因为时间可以具有不同的格式,并且它们之间的转换既不是线性的也不是简单的。每个“时间”都包含一个同步器来处理转换,并确保它们具有相同的,正确初始化的同步器,我使用TimeFactory。TimeFactory只有一个实例,并且在应用程序范围内,因此它可以容纳单例,但是由于它是可变的,因此我不想将其设置为单例。 在我的应用中,很多类都需要创建Time对象。有时,这些类是深层嵌套的。 假设我有一个类A,其中包含类B的实例,依此类推,直到类D。类D需要创建Time对象。 在我的幼稚实现中,我将TimeFactory传递给类A的构造函数,然后将其传递给类B的构造函数,依此类推,直到类D。 现在,假设我有几个类(如TimeFactory)和几个类层次结构(如上一个类):我失去了使用依赖注入获得的所有灵活性和可读性。 我开始怀疑我的应用程序中是否没有主要的设计缺陷……或者这是使用依赖注入的必要弊端? 你怎么看 ?

9
依赖注入:我应该使用框架吗?
我最近在一个Python项目中工作,我们在其中进行了大量依赖注入(因为必须使该应用程序可测试),但是我们没有使用任何框架。有时手动连接所有依赖项可能有点乏味,但总体来说效果很好。 当必须在多个位置创建对象时,我们只需一个函数(有时是该对象的类方法)即可创建生产实例。每当我们需要该对象时,都会调用此函数。 在测试中,我们做同样的事情:如果多次需要创建对象的“测试版本”(即由模拟对象支持的真实实例),我们就有一个函数来创建此“测试版本”类,用于测试。 就像我说的那样,总体来说效果很好。 我现在正在进入一个新的Java项目,并且我们正在决定是使用DI框架还是手动进行DI(例如上一个项目)。 请说明使用DI框架的工作方式会有所不同,以及以什么方式比手动“原始”依赖项注入更好或更坏。 编辑:我也想补充一个问题:您是否亲眼目睹了没有框架的手动执行DI的任何“专业级”项目?

4
在构造函数中合法的“实际工作”?
我正在设计,但是一直遇到障碍。我有一个特定的类(ModelDef),它实际上是通过解析XML模式(例如DOM)构建的复杂节点树的所有者。我想遵循良好的设计原则(SOLID),并确保生成的系统易于测试。我打算使用DI来将依赖项传递到ModelDef的构造函数中(以便在测试过程中可以根据需要轻松地将其替换掉)。 不过,我正在努力的是创建节点树。该树将完全由简单的“值”对象组成,而这些对象无需独立测试。(但是,我仍然可以将抽象工厂传递到ModelDef中,以帮助创建这些对象。) 但是我一直在读,构造函数不应该做任何实际的工作(例如Flaw:Constructor可以进行实际工作)。如果“实际工作”意味着构造重量较重的相关对象,而以后可能希望将其存根进行测试,则这对我来说非常有意义。(这些应通过DI传递。) 但是像该节点树这样的轻量级对象呢?必须在某个地方创建树,对不对?为什么不通过ModelDef的构造函数(例如使用buildNodeTree()方法)呢? 我真的不想在ModelDef之外创建节点树,然后再通过(通过构造函数DI)将其传递进去,因为通过解析架构来创建节点树需要大量复杂的代码-需要进行彻底测试的代码。我不想将其委托给“胶合”代码(这应该是相对琐碎的,并且可能不会被直接测试)。 我曾考虑过将代码创建节点树放在一个单独的“构建器”对象中,但是犹豫称它为“构建器”,因为它与“构建器模式”并不完全匹配(后者似乎与消除伸缩无关。构造函数)。但是,即使我将其称为其他名称(例如NodeTreeConstructor),也只是为了避免让ModelDef构造函数构建节点树而感到有些破绽。它必须建在某个地方。为什么不在要拥有它的对象中?

7
在.NET中实现DI的“正确”方法是什么?
我希望在相对较大的应用程序中实现依赖注入,但是对此没有经验。我研究了概念和可用的IoC和依赖注入程序的一些实现,例如Unity和Ninject。但是,有一件事让我难以理解。如何在应用程序中组织实例创建? 我正在考虑的是,我可以创建一些特定的工厂,其中将包含为某些特定的类类型创建对象的逻辑。基本上是一个静态类,带有一个调用此类中静态内核实例的Ninject Get()方法的方法。 它是在我的应用程序中实现依赖注入的正确方法还是我应该根据其他原则实现它?

2
域驱动设计-实体问题中的外部依赖关系
我想启动域驱动设计,但是在开始之前我想解决一些问题:) 假设我有一个网上论坛和用户,当用户想要加入网上论坛时,我正在调用groupsService.AddUserToGroup(group, user)method。在DDD中,我应该这样做group.JoinUser(user),看起来不错。 如果我有一些添加用户的验证规则,或者将用户添加到组中时需要启动一些外部任务,则会出现问题。拥有这些任务将导致实体具有外部依赖性。 例如-限制用户最多只能参加3个小组。这将需要从group.JoinUser方法内部进行DB调用来验证这一点。 但是,实体依赖于某些外部服务/类这一事实在我看来并不那么好,也不是“自然的”。 在DDD中处理此问题的正确方法是什么?

4
函数式编程是否可以替代依赖项注入模式?
我最近读了一本书,名为《用C#进行函数式编程》,我发现函数式编程的不可变和无状态本质可以实现与依赖注入模式相似的结果,并且可能甚至是更好的方法,尤其是在单元测试方面。 如果对这两种方法都有经验的人可以分享他们的思想和经验以回答主要问题,我将不胜感激:函数式编程是否可以替代依赖项注入模式?

6
使用DI / IoC是否应该删除所有出现的“ new”关键字?
使用依赖注入和控制反转容器是否应该从代码中删除所有出现的“ new”关键字? 换句话说,是否应该将每个对象/依赖项(无论多么简单或短暂)都“注册”到IoC容器中,并注入到需要使用它们的方法/类中? 如果不是,您如何在new关键字IoC容器中注册依赖项/对象与通过关键字“内联”创建的具体引用之间划清界限?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.