今日已更新 412 条资讯 | 累计 19972 条内容
关于我们

I've been doing Dependency Injection in Node.js without decorators for 9 years. Here's why I still think it's the right call.

Mauro Gadaleta 2026年06月18日 20:55 3 次阅读 来源:Dev.to

Ok so first, let me be honest. This post is partly me venting. I've been maintaining node-dependency-injection for about 9 years now. 300 stars on GitHub. Not exactly viral. And every time I look at InversifyJS or tsyringe climbing in popularity I think "yeah, but at what cost". So let me explain my problem with decorators. The coupling nobody talks about When you write this: @ Injectable () export class UserService { constructor (@ Inject ( MAILER_TOKEN ) private mailer : IMailer ) {} } Where does that @Injectable() live? In your DI framework. Which means your UserService — which is domain logic, business rules, the thing that should outlive any framework decision — now has a direct dependency on your IoC container library. Your domain knows about your infrastructure. That's the wrong direction. I know, I know. "It's just a decorator, it doesn't do anything". But it's still an import. It's still coupling. And if you ever want to swap the container, or move that service somewhere else, or just test it without spinning up the whole container — you now have to think about it. With NDI, your service is just a class: export class UserService { constructor ( private mailer : IMailer ) {} } That's it. No imports from my library. No decorators. No metadata. The service doesn't know it's being injected. The wiring lives completely outside — in a YAML file or in a bootstrap file. Your domain stays clean. "But Symfony does decorators and it's fine" Symfony doesn't use decorators in services actually. The DI config is external — YAML, XML, PHP config files. Your service is just a PHP class. That's literally what inspired NDI from the beginning. What NDI actually does Quick example. You have two payment providers and you want to inject the right one based on context: services : payment.stripe : class : ' payments/StripePayment' keyed : group : payment key : stripe default : true payment.paypal : class : ' payments/PaypalPayment' keyed : group : payment key : paypal checkout.ser

本文内容来源于互联网,版权归原作者所有
查看原文