好的,所以我认为我对IoC以及与之相关的模式,依赖注入和服务定位器模式有基本的了解。 从我所看到的,似乎依赖注入类构造函数更有利于松散耦合服务定位器。 如果我想从高级类中实例化一个对象,那么我无法理解并且无法真正找到任何关于它的内容,该怎么办?我是否更改了调用新类的类的构造函数?如果是这样,那就意味着我必须改变对该构造函数的每次调用以及每个调用该类调用的类的构造函数,以及对根的调用。这看起来非常麻烦且不安全。在这种情况下,服务定位器会更合适吗? 任何建议将不胜感激。
简单示例:
class car
void car(iBrand brand, iModel model){
_brand=brand;
_model=model;
}
class brand : iBrand
void brand (iModel model){
_model=model;
}
class model : iModel
void model()
这是一个特别粗略的例子,但希望能得到我的观点。这些对象中的每一个都实例化下面的类。现在,如果我想在模型类中创建一个iEngine,这是否意味着它必须从顶部一直向下传递,包括进入汽车构造函数?
class car
void car(iBrand brand, iModel model, iEngine engine){
_brand=brand;
_model=model;
_engine=engine;
}
谢谢, ħ
答案 0 :(得分:1)
应用程序中应该只有一个地方可以实例化injectable classes; Composition Root。所以应该没有人但组合根调用组件的构造函数。它应该是组成对象图的组合根。
依赖项应该只包含在类型的构造函数中,如果该类型直接使用该依赖项。在您的示例中,Brand
和Car
都取决于IModel
,但如果Car
不需要直接与IModel
交互,则不应将模型注入Car
。或者想象一个取决于UsersController
的{{1}}类。如果需要使用某些日志记录扩展IUserRepository
,则UserRepository
不应该知道这一点。您应该在UsersController
的构造函数中注入ILogger
,UserRepository
不受影响。
由于组合根是唯一调用构造函数的地方,并且添加依赖项不应该遍及整个依赖关系图,更改构造函数应该意味着只有组合根受到影响(当然除了有问题的类)。如果您使用DI框架,在大多数情况下甚至可以防止必须更改任何内容。