Questions tagged «inversion-of-control»

控制反转(IoC)是一种抽象原理,描述了某些软件体系结构设计的一个方面,其中与过程编程相比,系统的控制流是反向的。


7
为什么控制反转以这种方式命名?
这些话invert或control根本不使用在我见过的定义来定义控制反转。 定义 维基百科 控制反转(IoC)是一种编程技术,在此以面向对象编程的形式表示,其中对象耦合在运行时由汇编程序对象绑定,通常在编译时使用静态分析是未知的。〜http://en.wikipedia.org/wiki/Inversion_of_control 马丁·福勒 控制反转是Java社区中的一种常见模式,可帮助连接轻量级容器或将来自不同项目的组件组装到一个内聚的应用程序中。〜基于 http://www.martinfowler.com/articles/injection.html (改写) 那么,为什么将控制反转称为控制反转?什么控制被颠倒了?有没有一种方法可以使用术语“ 反转和控制”来定义“控制反转”?


7
单一责任原则-如何避免代码碎片化?
我正在一个团队中,团队负责人是SOLID开发原则的坚决拥护者。但是,他缺乏将复杂软件发布出去的大量经验。 在某种情况下,他将SRP应用于本来已经很复杂的代码库中,而现在该代码库变得非常分散,难以理解和调试。 现在,我们不仅遇到代码碎片问题,而且遇到封装问题,因为某个类中可能是私有或受保护的方法被判断为代表“更改原因”,并已提取到公共或内部类和接口中,与应用程序的封装目标不符。 我们有一些类构造函数,它们接收20个以上的接口参数,因此我们的Io​​C注册和解析本身已成为一个庞然大物。 我想知道我们是否可以使用任何“远离SRP的重构”方法来帮助解决其中一些问题。我已经读到如果创建多个空的粗粒度类来“包装”多个紧密相关的类以提供对它们功能总和的单点访问(即模仿一个较小的类),则它不会违反SOLID过度采用SRP的类实施)。 除此之外,我想不出一种解决方案,该解决方案将使我们能够务实地继续我们的开发工作,同时又使每个人都满意。 有什么建议么 ?

5
IOC容器违反了OOP原则
IOC容器的目的是什么?合并的原因可以简化为以下内容: 当使用OOP / SOLID开发原则时,依赖注入会变得混乱。您可能具有顶层入口点,这些入口点管理着位于其自身下方的多个级别的依赖关系,并通过构造递归传递依赖关系,或者您在工厂/构建器模式和接口中有一些重复的代码,可以根据需要构建依赖关系。 没有OOP / SOLID方式可以执行此操作并拥有超级漂亮的代码。 如果上述陈述是正确的,那么IOC容器该如何做?据我所知,他们没有采用手动DI无法完成的未知技术,因此唯一的解释是IOC容器通过使用静态对象私有访问器来打破OOP / SOLID原则。 IOC容器是否在幕后打破了以下原则?这是真正的问题,因为我有很好的理解,但是感觉到其他人有更好的理解: 范围控制。范围是我对代码设计做出几乎所有决定的原因。块,本地,模块,静态/全局。范围应该非常明确,在块级别尽可能多,而在静态级别则尽可能少。您应该看到声明,实例化和生命周期的结尾。只要我明确指出,我相信该语言和GC可以管理范围。在我的研究中,我发现IOC容器将大多数或所有依赖项设置为静态,并通过幕后的一些AOP实现对其进行控制。所以没有什么是透明的。 封装。封装的目的是什么?我们为什么要保留私人会员呢?出于实际原因,因此我们的API的实现者无法通过更改状态(应由所有者类管理)来破坏实现。但是,出于安全原因,也不会发生注入超过我们的成员国并绕过验证和类控制的情况。因此,在编译之前以某种方式注入代码以允许外部访问私有成员的任何东西(模拟框架或IOC框架)都非常庞大。 单一责任原则。从表面上看,IOC容器似乎使事情更清洁。但是想象一下,如果没有帮助程序框架,您将如何完成相同的任务。您将传递带有十几个依赖项的构造函数。这并不意味着用IOC容器将其掩盖,这是一件好事!这是重构代码并遵循SRP的标志。 打开/关闭。就像SRP并非仅是类一样(我将SRP应用于单一职责范围,更不用说方法了)。打开/关闭不仅是不更改类代码的高级理论。这是一种了解程序配置并控制要更改和扩展的内容的实践。IOC容器可以部分地完全更改类的工作方式,因为: 一种。主要代码没有确定切换出依赖项,而是框架配置。 b。范围可以在不受调用成员控制的时间进行更改,而是由静态框架在外部确定。 因此,该类的配置不是真正封闭的,它会根据第三方工具的配置自行更改。 这是一个问题,是因为我不一定是所有IOC容器的大师。尽管IOC容器的想法不错,但它们似乎只是掩盖了糟糕的实现的外观。但是,为了完成外部Scope控制,私有成员访问和延迟加载,必须进行许多非平凡的可疑事情。AOP很棒,但是通过IOC容器完成AOP的方式也值得怀疑。 我可以相信C#和.NET GC可以完成我期望的工作。但是我不能再信任第三方工具来改变我的已编译代码,以执行我无法手动执行的操作的变通办法。 EG:实体框架和其他ORM创建强类型对象并将其映射到数据库实体,并提供样板功能来执行CRUD。任何人都可以建立自己的ORM,并继续手动遵循OOP / SOLID原则。但是这些框架对我们有帮助,因此我们不必每次都重新发明轮子。看来,IOC容器可以帮助我们有目的地围绕OOP / SOLID原则开展工作并加以掩盖。

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

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


2
如何通过依赖项注入管理配置?
我是DI / IOC的忠实粉丝。它非常适合处理/抽象出硬依赖关系,并使生活更轻松。 但是,我对此有些疑惑,我不确定该如何解决。 DI / IOC的基本思想是,当实例化对象时,其所有依赖项都将在构造函数中预先填充。 但是恕我直言,构造函数有几种类型的参数(尤其是当您的对象是不可变的时)。 依赖关系(您的对象正常工作所需的对象) 配置(有关工作所需环境的信息) 参数(完成工作的数据) 我发现IOC可以很好地处理依赖关系。但我仍在尝试找出与其他两个人打交道的最佳方法。但是,由于构造函数是要由IOC容器运行的,因此似乎需要将这些项目放入IOC容器中。 我想知道人们采用什么策略/模式,人们发现了哪些优点和缺点。 注意 我知道这是一个高度主观的问题,并且根据SE指南已尝试将其设为“好”主观问题。

1
编写框架时的依赖注入/ IoC容器实践
我在许多项目中都为.Net使用了各种IoC容器(Castle.Windsor,Autofac,MEF等)。我发现它们往往经常被滥用,并鼓励许多不良行为。 是否有用于IoC容器的既定实践,特别是在提供平台/框架时?作为框架编写者,我的目标是使代码尽可能简单和易于使用。我宁愿写一行代码来构造一个对象,而不是十行甚至两行。 例如,我注意到了一些代码气味,并且对以下内容没有好的建议: 构造函数的大量参数(> 5)。创建服务往往很复杂;尽管所有组件很少是可选的(除了可能在测试中),所有依赖项都是通过构造函数注入的。 缺乏私人和内部阶级;这可能是使用C#和Silverlight的特定限制,但是我对如何解决它感兴趣。如果所有的类都是公共的,很难说框架接口是什么。它使我可以访问我可能不应该接触的私人部件。 将对象生命周期耦合到IoC容器。手动构造创建对象所需的依赖项通常很困难。对象生命周期通常由IoC框架管理。我见过大多数班级都注册为Singletons的项目。您缺乏明确的控制,还被迫管理内部(与上述要点有关,所有类都是公共的,因此您必须注入它们)。 例如,.Net框架具有许多静态方法。例如DateTime.UtcNow。很多次,我都将这种包装和注入作为构造参数。 依赖于具体的实现使我的代码难以测试。注入依赖关系会使我的代码难以使用-特别是在类具有许多参数的情况下。 如何提供可测试的界面以及易于使用的界面?最佳做法是什么?

3
请用IoC容器卖给我
我已经看到一些建议在代码中使用IoC容器的方法。动机很简单。采取以下依赖项注入代码: class UnitUnderTest { std::auto_ptr<Dependency> d_; public: UnitUnderTest( std::auto_ptr<Dependency> d = std::auto_ptr<Dependency>(new ConcreteDependency) ) : d_(d) { } }; TEST(UnitUnderTest, Example) { std::auto_ptr<Dependency> dep(new MockDependency); UnitUnderTest uut(dep); //Test here } 进入: class UnitUnderTest { std::auto_ptr<Dependency> d_; public: UnitUnderTest() { d_.reset(static_cast<Dependency *>(IocContainer::Get("Dependency"))); } }; TEST(UnitUnderTest, Example) { UnitUnderTest uut; //Test here …

3
我得到依赖注入,但是有人可以帮助我了解对IoC容器的需求吗?
如果这似乎又是一个重复的问题,我深表歉意,但是每次我找到有关该主题的文章时,它大多只是在谈论DI是什么。因此,我得到了DI,但我试图了解每个人似乎都在使用的IoC容器的需求。IoC容器的目的真的只是为了“自动解决”依赖项的具体实现吗?也许我的类往往没有几个依赖关系,也许这就是为什么我认为没什么大不了的,但是我想确保我正确地理解了容器的效用。 我通常将我的业务逻辑分解为一个可能看起来像这样的类: public class SomeBusinessOperation { private readonly IDataRepository _repository; public SomeBusinessOperation(IDataRespository repository = null) { _repository = repository ?? new ConcreteRepository(); } public SomeType Run(SomeRequestType request) { // do work... var results = _repository.GetThings(request); return results; } } 因此,它仅具有一个依赖性,在某些情况下可能具有第二或第三依赖性,但并非经常如此。因此,任何调用此方法的都可以传递其自己的存储库,也可以允许其使用默认存储库。 就我对IoC容器的当前了解而言,该容器所做的只是解析IDataRepository。但是,如果这就是全部,那么我就没有看到太多的价值,因为当没有依赖项传入时,我的操作类已经定义了一个回退。所以我唯一想到的另一个好处是,如果我有多个操作,例如这个使用相同的后备仓库,我可以在注册表/工厂/容器的一个地方更改该仓库。那太好了,是吗?

5
使用Func代替IoC接口
上下文:我正在使用C# 我设计了一个类,为了隔离它并使单元测试更容易,我传入了它的所有依赖关系。它在内部没有对象实例化。但是,不是引用接口来获取所需的数据,而是让它引用通用的Funcs返回所需的数据/行为。当注入其依赖项时,我可以使用lambda表达式来实现。 对我来说,这似乎是一种更好的方法,因为在单元测试期间我不必做任何繁琐的模拟。另外,如果周围的实现有根本变化,则只需要更改工厂类即可;无需更改包含逻辑的类。 但是,我之前从未见过IoC这样做,这使我认为我可能会缺少一些潜在的陷阱。我唯一想到的是与未定义Func的C#早期版本的轻微不兼容,在我看来,这不是问题。 使用泛型委托/高阶函数(例如Func for IoC),而不是使用更具体的接口时,是否存在任何问题?

5
我应该在实现之前编写接口API吗?
最近,我一直在研究更多的“有组织的”编程,并且我一直在学习应该对接口而不是对实现进行编程。考虑到这一点,在可能的情况下为项目编写实现之前,最好在接口中“略过”项目吗? 如果是这种情况,那么在使用第三方库(即Lidgren)的情况下,我是否也应该将它们包装在接口中并通过IOC容器进行解析,还是可以将它们公开给接口?

5
遵循TDD是否不可避免地导致DI?
我学会了同时进行测试驱动开发(TDD),依赖注入(DI)和控制反转(IoC)。当我使用TDD编写代码时,我总是最终在类的构造函数中使用DI。我想知道这是因为我学会了如何进行TDD,还是这是TDD的自然副作用。 所以我的问题是:遵循TDD原理和编写不依赖外部服务的单元测试是否不可避免地导致DI?

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.