【问题标题】:Cannot Inject Dependency Into Derived Class无法将依赖注入派生类
【发布时间】:2020-01-20 18:54:12
【问题描述】:

我有一个相对简单的设置,包含三个类。我正在使用inversify 进行依赖注入。但是当将MessageBroker 类注入派生类Repository 时,MessageBroker 是未定义的:

import 'reflect-metadata';
import { injectable, inject, Container, unmanaged } from 'inversify';

const container = new Container();

const registerProviders = (...providers: any[]) =>
  providers.forEach(provider => container.bind(provider.name).to(provider));

const getProvider = (provider): any => container.get(provider.name);

@injectable()
export class MessageBroker {
  start = () => console.log('init message broker');
}

@injectable()
export abstract class Repository {
  @inject(MessageBroker.name) private mb: MessageBroker;

  constructor(@unmanaged() protected readonly user: any) {}

  // this.mb is undefined
  initialize = () => this.mb.start();
}

@injectable()
export class UserRepository extends Repository {
  constructor() {
    super({ user: 'some object' });
    this.initialize();
  }
}

registerProviders(UserRepository, Repository, MessageBroker);

const repo: UserRepository = getProvider(UserRepository);

你可以自己试试。我创建了一个小型 GitHub 存储库:https://github.com/flolude/stackoverflow-inversify-injected-service-undefined

运行脚本时,我收到此错误:

/project/index.ts:22
  initialize = () => this.mb.start();
                             ^
TypeError: Cannot read property 'start' of undefined
    at UserRepository.Repository.initialize (/project/index.ts:22:30)
    at new UserRepository (/project/index.ts:29:10)
    at _createInstance (/project/node_modules/inversify/lib/resolution/instantiation.js:21:12)
    at Object.resolveInstance (/project/node_modules/inversify/lib/resolution/instantiation.js:41:18)
    at /project/node_modules/inversify/lib/resolution/resolver.js:72:42
    at Object.resolve (/project/node_modules/inversify/lib/resolution/resolver.js:96:12)
    at /project/node_modules/inversify/lib/container/container.js:319:37
    at Container._get (/project/node_modules/inversify/lib/container/container.js:310:44)
    at Container.get (/project/node_modules/inversify/lib/container/container.js:230:21)
    at getProvider (/project/index.ts:9:50)

附:将代码编译为 Javascript 时出现几乎相同的错误

【问题讨论】:

    标签: javascript typescript dependency-injection inversifyjs reflect-metadata


    【解决方案1】:

    您的 MessageBroker 仅设置在内存中,但从未被实例化,这就是它得到未定义错误的方式。在您的构造函数中,您需要设置

    this.mb = new MessageBroker();

    不使用上述代码行的另一种方法是在 MessageBroker 类中添加一个空参数签名构造函数。

    【讨论】:

    • 这不是违背了依赖注入的全部目的吗?如果你能展示你的第二种方法的例子会很酷:)
    • DI 仍然需要存在的东西。 export class MessageBroker { constructor() {} start = () => console.log('init message broker'); }
    • 另一个示例,这是一个 Angular 4 示例,但仍然使用 Typescript:@Injectable() export class ReferenceNumberTableService { constructor(private globals: GlobalService, private http: Http) { } //These GlobalService is also an Injectable Service. and Http is an @angular/core import. //Other methods here. } 在组件文件中使用:constructor(readonly referenceNumberTableService: ReferenceNumberTableService) { }
    • @inject(MessageBroker.name) private mb: MessageBroker; 实际上并没有按照您需要的方式注入它。如果您想在没有 Message Broker 的新实例的情况下注入它,则必须将 MessageBroker 放入您的 Repository 构造函数中,方法是添加:private mb: MessageBroker 并删除上述行。您可以在我的示例中看到我是如何做到这一点的,其中 ReferenceTableService 是一个可注入服务,我将它粘贴在组件的构造函数中。那也行。如果不这样做,您需要创建一个新实例。构造函数设置将为您创建一个新的。
    • 好吧,这是有道理的。但后来我收到一个错误,告诉我我需要在UserRepositorysuper() 中提供一个参数...所以我想我必须将MessageBroker 注入UserRepository 并将其传递给super() ?
    猜你喜欢
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多