我使用InversifyJS和容器。
我想在构造函数中注入 templateEngine 并传递 args (主机,端口等...... )。
const container = new Container();
container.bind<MailerInterface>(TYPES.Mailer).to(NodeMailer);
我的邮件程序类:
import * as nodemailer from "nodemailer";
import {TemplateEngineInterface} from "../../Domain/TemplateEngine/TemplateEngineInterface";
import TYPES from "../../../../config/inversify.types";
import {inject, injectable, named} from "inversify";
@injectable()
export class NodeMailer implements MailerInterface {
private transporter: any;
private templateEngine: TemplateEngineInterface;
constructor(
@inject(TYPES.TemplateEngine) templateEngine: TemplateEngineInterface,
host: string,
port: number,
secure: boolean,
username: string,
password: string
) {
this.templateEngine = templateEngine;
this.transporter = nodemailer.createTransport({
host: host,
port: port,
secure: secure,
auth: {
user: username,
pass: password
}
});
}
}
如何使用inject或其他方法在构造函数中传递参数?
答案 0 :(得分:1)
您有几个选择。
constructor(
@inject(TYPES.TemplateEngine) templateEngine: TemplateEngineInterface,
@inject(TYPES.MailerConfig) @named("host") host: string,
@inject(TYPES.MailerConfig) @named("port") port: number,
@inject(TYPES.MailerConfig) @named("secure") secure: boolean,
@inject(TYPES.MailerConfig) @named("username") username: string,
@inject(TYPES.MailerConfig) @named("password") password: string
) {
类型只是:
const TYPES = { MailerConfig: Symbol.for("MailerConfig") }
绑定:
type MailerConfig = string|boolean|number;
container.bind<MailerConfig>(TYPES.MailerConfig)
.toConstantValue("localhost")
.whenTargetNamed("host");
container.bind<MailerConfig>(TYPES.MailerConfig)
.toConstantValue(2525)
.whenTargetNamed("port");
container.bind<MailerConfig>(TYPES.MailerConfig)
.toConstantValue(true)
.whenTargetNamed("secure");
container.bind<MailerConfig>(TYPES.MailerConfig)
.toConstantValue("root")
.whenTargetNamed("username");
container.bind<MailerConfig>(TYPES.MailerConfig)
.toConstantValue("toor")
.whenTargetNamed("password");
如果您打算这样做,我建议您创建帮助程序以减少所需的样板。
type MailerConfig = string|boolean|number;
const bindMailerConfig = (ctr: Container, key: string, val: MailerConfig) =>
ctr.bind<MailerConfig>(TYPES.MailerConfig)
.toConstantValue(key)
.whenTargetNamed(val);
bindMailerConfig(container, "localhost", "host");
bindMailerConfig(container, 2525, "port");
bindMailerConfig(container, true, "secure");
bindMailerConfig(container, "root", "username");
bindMailerConfig(container,"toor", "password");
const injectNamed = (typeId: any) => (name: string) =>
(target: any, targetKey: string, index?: number) => {
inject(typeId)(target, targetKey, number);
named(name)(target, targetKey, number);
};
const injectMailerConfig = injectNamed(TYPES.TemplateEngine);
constructor(
@inject(TYPES.TemplateEngine) templateEngine: TemplateEngineInterface,
@injectMailerConfig("host") host: string,
@injectMailerConfig("port") port: number,
@injectMailerConfig("secure") secure: boolean,
@injectMailerConfig("username") username: string,
@injectMailerConfig("password") password: string
) {
@injectable()
export class NodeMailer implements MailerInterface {
private transporter: any;
private templateEngine: TemplateEngineInterface;
constructor(
@inject(TYPES.TemplateEngine) templateEngine: TemplateEngineInterface,
) {
this.templateEngine = templateEngine;
this.transporter = null;
}
public initialize(host, port, secure, username, password) {
if (this.transporter) {
return this.transporter;
}
this.transporter = nodemailer.createTransport({
host: host,
port: port,
secure: secure,
auth: {
user: username,
pass: password
}
});
return this.transporter;
}
public send() {
if (this.transporter === null) {
throw new Error("You must invoke initialize!");
}
// ...
}
}
两步初始化可以很好地与factory一起使用。