CodePark/ questions / Providers & dependency injection
START PRACTICINGPRACTICE
Backend question · NestJS › Providers & dependency injection

You want consumers to depend on an interface MailSender, with SmtpMailSender as the implementation. What is the correct way to inject it?

Register { provide: "MAIL_SENDER", useClass: SmtpMailSender } and inject with @Inject("MAIL_SENDER") private mail: MailSender

Register a string token with useClass and inject it with @Inject("MAIL_SENDER"). Interfaces don't exist at runtime. So Nest can't use them as tokens, and it can't read them from type metadata. You keep the interface only as the TypeScript type.

"
constructor(private mail: MailSender) {} with providers: [SmtpMailSender]" is wrong, because Nest has no runtime type to match. "constructor(@Inject(MailSender) private mail: MailSender) {}" is wrong for the same reason: MailSender is not a value at runtime. "Mark MailSender with @Injectable() so it can be used as a token" is wrong, because decorators can't be put on interfaces.

An abstract class would also work as a token. An interface never does.