1

今天我将一个 js电子项目切换到 typescript,问自己是否有与angular的依赖注入等价的东西。由于Angular Universal似乎处于非常早期的状态,并且根本没有将它与电子而不是express一起使用的文档,因此inversify似乎可以满足我的需求。也因为它比 Angular 更轻巧,因为我只需要 DI。

我最终尝试创建一个与NgModuleAngular 中的装饰器类似的装饰器。

import { app, Menu, ipcMain, BrowserWindow } from 'electron';
import { Container } from 'inversify';
import { DatabaseService } from 'core/database.service';

function servermodule(data: {providers: Array<any>}) {
  // Some code that instantiate the declarations array classes
  // Do they have to be returned, if I don't need a reference?

  let container = new Container();
  return (target: Object) => {
    for(const service of data.providers) {
      container.bind(service).toSelf();
    }
  }

}

它循环遍历提供者中的每个条目并将其绑定到 inversifys 容器对象。我想使用的这个功能如下。然后,用法将与 angulars 装饰器中的完全一样。

@servermodule({
  declarations: [
    // Some other classes, that maybe can get DatabaseService injected
  ],
  providers: [
    DatabaseService
  ]
})
export class AppModule { ...

例如,DatabaseService可能看起来像

 import { injectable } from 'inversify';

 @injectable()
 export class DatabaseService { ...

并且应该可以以角度样式注射,例如

import { inject } from 'inversify';
import { DatabaseService } from './database.service';

export class Models {
  constructor(@inject(DatabaseService) dbService: DatabaseService) { }
}

我不确定 inversify 的容器。它的范围仅在装饰器功能中吗?将它用作

container = new Container({ autoBindInjectable: true });

我如何正确地将其返回到AppModule? 我在 servermodule 装饰器中声明类的想法是个好主意吗?

现在我只收到以下关于 tsc 和电子执行的错误消息,但没有 ts linting 错误。

App threw an error during load
Error: Cannot find module 'database.service'

另一个想法/问题是:如果除了声明和提供者之外我还想要一个导入属性。那么通过装饰器修改构造函数并导入这些类会是一个好主意吗?

谢谢!

4

1 回答 1

2

关于这个问题,半年前,我致力于为一个类似于 Angular 的分层 DI 实现装饰器函数,并将它们捆绑在一个npm 包 fl-node-di中。有了它,您可以生成模块

FlModule({
  imports: [ AnotherModule ] // imports other FlModules
  providers: [ MyService ] // adds Injectables() to the modules container
  declaration: [] // same as providers but immediatly creates an instance
  exports: [] // places the Injectable() in the parents container
})
export class MyModule {}

另一个模块可能看起来像

FlModule({
  declarations: [ MyComponent ]
})
export class AnotherModule {}

该组件可能看起来像

@Component()
export class MyComponent {
  constructor (@Inject(MyService) myService: MyService) {}
}

注意服务。该服务在父模块中提供,因此是分层的。

于 2018-09-23T09:52:36.090 回答