1

我正在尝试在我的打字稿应用程序中使用 InversifyJS 进行依赖注入。当我按照文档中给出的简单示例进行操作时,一切正常。但是,依赖项不会注入到依赖项链中较低的类中。希望这个例子能让我想说的更清楚。我尽可能多地删除了样板:

EmployeeFactory.ts

@injectable()
class EmployeeFactory {
    create(employeeName: string): Employee {
        /*
         * I think my error comes from the use of
         * the new keyword right here. Not sure though.
         */
        return new Employee(employeeName);
    }
}

公司.ts

@injectable()
class Company {
    @inject('EmployeeFactory') private employeeFactory: EmployeeFactory;

    public getEmployees() {
        return [
            this.employeeFactory.create('Alice'),
            this.employeeFactory.create('Bob')
        ]
    }

}

员工.ts

@injectable()
class Employee  {
    @inject('EmployeeFactory') private employeeFactory: EmployeeFactory;
    constructor(readonly name: string) {

    }

    public getBoss(): Employee {
        //TypeError: Cannot read property 'create' of undefined
        return this.employeeFactory.create("Boss man")
    }
}

然后这是我运行以获取错误的代码

import { Container } from "inversify";

let myContainer = new Container();
myContainer.bind<EmployeeFactory>("EmployeeFactory").to(EmployeeFactory);
myContainer.bind<Company>('Company').to(Company);
myContainer.bind<Employee>('Employee').to(Employee);

let oscorp: Company = myContainer.get<Company>('Company');

let employees: Employee[] = oscorp.getEmployees();
console.log('employees', employees);
// PRINTS: employees [ Employee { name: 'Alice' }, Employee { name: 'Bob' } ]

let boss = employees[0].getBoss(); 
console.log('boss', boss);

所以我的问题是:如何在我的应用程序中没有“myContainer”的情况下将 EmployeeFactory 注入到 Employee 类中?我确定我遗漏了有关 InversifyJS 的一些重要信息,因此感谢您提供任何帮助。

4

1 回答 1

0

这里的问题是这个类Employee是用 operator 创建的new,而不是用 inversifyJS 创建的。因此,您只需通过 JS 创建新实例,无需任何依赖注入。

如果你只想让你的代码工作,你可以简单地将你的代码重写为

EmployeeFactory.ts

@injectable()
class EmployeeFactory {
    create = (employeeName: string): Employee => {
        return new Employee(this, employeeName);
    }
}

员工.ts

@injectable()
class Employee  {
    constructor(
        private _employeeFactory: EmployeeFactory,
        readonly name: string,
    ) {}

    public getBoss(): Employee {
        return this._employeeFactory.create("Boss man")
    }
}

但是如果你想让它成为 inversify 的方式,那么你需要使用 Factory Injection: https ://github.com/inversify/InversifyJS/blob/master/wiki/factory_injection.md

然后您需要将绑定中的代码更改为

myContainer.bind<Company>('Company').to(Company);
myContainer.bind<Employee>('Employee').toConstructor(Employee);
container.bind<interfaces.Factory<Employee>>('Factory<Employee>').toFactory<Employee>((context: interfaces.Context) => {
    return (name: string) => {
        const EmployeeConstructor = context.container.get<Employee>('Employee');
        return new EmployeeConstructor(name);
    };
});

公司.ts

@injectable()
class Company {
    @inject('Factory<Employee>') private employeeFactory: (name: string) => Employee;

    public getEmployees() {
        return [
            this.employeeFactory('Alice'),
            this.employeeFactory('Bob')
        ]
    }

}
于 2019-11-26T10:36:39.527 回答