Typescript在类中注入和参数

时间:2017-12-07 17:12:51

标签: typescript inject inversifyjs

我使用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或其他方法在构造函数中传递参数?

1 个答案:

答案 0 :(得分:1)

您有几个选择。

A)注入配置

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
) {

B)两步初始化

@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一起使用。