![]() |
1
23
简短的回答: 不 ,您的公司没有有效地使用DI。 稍微长一点的答案:主要的问题是所有的类都有 默认构造函数 . 在这种情况下,如何解决依赖关系? 您的构造函数或者具有这样的硬编码依赖项:
在这种情况下,如果不重新编译该应用程序,就不能改变依赖项。 更糟糕的是,他们可能会使用 Static Service Locator anti-pattern :
DI容器应该解析应用程序的 Composition Root 别挡道。 一般来说,最好用 配置上的约定 通过在代码中使用启发式方法来配置容器。XML配置应该为少数需要重新配置依赖项的情况保留。 无需重新编译 ,它应该只是一个子集。简而言之,我认为在代码中配置容器没有固有的问题。实际上,这是首选的方法。 每个接口只有一个实现也不是问题。这是一个开始,如果应用程序是真正松散耦合的,那么它是 不断打开机遇之窗 . 迟早,您很可能会引入替代实现,但如果接口已经就位,并且整个代码基都遵循 Liskov Substitution Principle . |
![]() |
2
3
根据数据类型,我认为您指的是绑定。例如,
你确定?如果是这样的话 能够 闻一闻。不过,你已经说过这是一个很大的应用程序。如果正在进行任何单元测试(或自动测试),那么每个实现都有一个接口是完全有效的。
是的,据我所知。对于任何形式的自动化测试,在对象内创建依赖项都是一件糟糕的事情。通过使用IOC容器,可以在实际将生产代码连接在一起时移除类的复杂连接。这简化了应用程序,并允许作为开发人员的您专注于特性和其他任务,而不是确保实际构建整个东西。 此外,通过反转控件,对应用程序的模块化部分进行更改非常容易。例如,假设您希望切换模块以获得更好的版本。使用IOC容器,您只需修改一行或两行绑定。如果没有IOC,您必须手动遍历应用程序,并确保其内部连接正确。 这是一个与你最后一点有关的好问题,关于 why you should use IOC 直接人工方法。 |
![]() |
3
1
我相信其他人会贴出更详细的答案,但我有:
有一种趋势( at least some )使用代码而不是XML配置来注册依赖项的IOC/Dependency注入框架。主要的好处是,在编译时,您知道是否有错误的连接。例如,如果您决定添加/删除一个构造函数参数,那么当您的配置不同步时,您的代码实际上不会编译(并且它会防止打字错误在运行时显示为随机的空引用异常)。
我不太确定“一个接口实现”是什么意思。如果您的意思是接口向下投射到实现它们的对象上,那么这绝对不是犹太洁食。如果不是这样,那么编码到接口而不是具体的实现是有好处的。主要的功能显然是能够在单元测试中使用支持所述接口的模拟对象。编程到接口(理论上)迫使您使代码更松散地耦合,这有助于测试性。它还打开了一些非常酷的设计选项,比如这个 Build a generic typesafe DAO with Hibernate and Spring AOP 一个。
这也不一定是坏事。我认为一般来说,经验法则是,如果依赖关系对于类执行其函数至关重要,那么应该使用构造函数注入。如果不是(日志记录可能是最常用的例子),那么属性注入是一个更合适的选项。虽然我不熟悉CaseWistor,但我知道至少有些Java IOC容器不支持早期版本中的构造函数注入(如果熟悉CaseWistor的人可以对此发表评论,那太棒了)。如果Castle Windsor在早期版本中没有此功能,这也可能导致您在系统中看到的设计。
就使用IOC和呼叫而言
|
![]() |
4
0
你的前两个问题不是真正的问题(finglas描述了原因)。 我认为“所有注册的数据类型都有一个默认的构造函数”是一种代码味道(假设类直接从IOC容器加载依赖项)。当发生这种情况时,其1)一个应用程序入口点,在该入口点可以从IOC容器中获取对象(无论如何,您可能需要初始化该IOC容器),或2)一个可以使用工厂的地方。 不鼓励使用默认的构造函数填充依赖项。原因是你在复制如何创建类的知识。理想情况下,每个类甚至不必知道IOC容器在哪里——这是应用程序入口点的工作。 听起来你们公司的IOC使用总体上还不错。 |
![]() |
Nikolay K · Castle Windsor从类内拦截方法调用 9 年前 |
![]() |
user3643376 · Unity ResolveAll泛型接口 9 年前 |
![]() |
Ilias Kouroudis · 绕过Laravel服务提供商 9 年前 |
![]() |
Wojciech Kozaczewski · 实体框架-容器的并发使用 9 年前 |
![]() |
vishal mane · 在不使用容器的情况下从配置进行统一拦截 10 年前 |