DI容器在错误使用时(即在大多数情况下)不仅是代码污染者 ,而且是绝对的恶魔。
这是静态依赖
DI容器经常从各地调用。 在这种情况下,DI容器只是一个服务定位器 ,它是一个单例。 单例具有大量方法。 除此之外,它还引入了隐藏的依赖关系 。 那可能是这样的:
class PaymentProcessor
{
public function purchase()
{
return DIPaymentModuleFactory:: me ()->purchase();
}
}
要纠正此错误,唯一的方法是仅在应用程序的最高级别上使用它,最好在应用程序启动的索引文件中使用它。 如果您以这种方式使用它-您是否真的仍然需要它? 无论如何你都不是。 已经是Catch-22了,还有两个要点。
它打破了最可靠的OOP隐喻之一
DI容器打破了David West在他的“ 对象思维”一书中谈到的乐高积木的隐喻。 我希望在一个地方实例化我的类,这个地方应该是任何请求或消息的入口。 他们的合作只能通过组成来实现。 可组合性是任何有抱负的对象思考者都追求的目标。
破坏凝聚力
而且,它打破了基本的OOP原则,即数据封装和公开行为。 为什么要实例化对象的方式对程序代码隐藏了? 为什么将它放在一些配置文件中 ? 真的,请考虑一下-废话! 这一点甚至更广泛。 为什么我们需要配置文件? 为什么某些数据的行为会被撕裂? 这正是14年前马丁·福勒(Martin Fowler)所说的,对吧? 每个人似乎都同意这一点。 但是,为什么我们继续遵循这个概念? 配置文件仅反映了过程的心态!
没有DI容器的生活
这是一个纯粹的依赖注入 。 这就是我的入口点通常的样子:
try {
echo
( new PurchaseOrder(
new LocalOrderStorage(
new NullOrderStorage()
),
new OrderId($inputParams[ 'order_id' ])
))
->newInvoice(
new InvoiceNumber(
new Vendor(
new LocalVendorStorage(),
new VendorId($inputParams[ 'vendor_id' ])
),
new VendorInvoiceNumber($inputParams[ 'vendor_invoice_number' ]),
new DateTime($inputParams[ 'date_time' ])
),
new VendorInvoiceNumber($inputParams[ 'vendor_invoice_number' ]),
new DateTime($inputParams[ 'date_time' ]),
new InvoiceAmount(
new Amount($inputParams[ 'amount' ]),
new Currency($inputParams[ 'currency' ])
)
)
->json()
;
} catch (Exxeption $exxeption) {
return
( new ErrorResult())
->json($exxeption->getCode(), $exxeption->getMessage())
;
}
太好了 加入我。
From: https://hackernoon.com/you-dont-need-a-dependency-injection-container-10a5d4a5f878