继承依赖注入 [英] Inherit Dependency injection

查看:47
本文介绍了继承依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个通用的api服务,以使与模型相关的服务更易于创建:

I want to create a generic api service in order to make model-related services easier to create:

export abstract class ModelService<T> {

    constructor(protected apiService: ApiService) {
        //ApiService is a service that wraps Http and adds signature , auth and serialization.
    }

    public getAll(): Observable<T[]> {
        return this.apiService.get<T[]>(this.modelClass, this.baseUrl);
    }
}

然后,我将创建管理模型 Foo 的服务:

then, I will create my service that manages model Foo:

@Injectabe()
export class FooService extends ModelService<Foo>{

}

但是当我调用 fooService.getAll().subscribe(...); 时,我收到一条错误消息,提示未定义 apiService (无法获取属性'get'的).

But when I call fooService.getAll().subscribe(...); I get an error saying that apiService is undefined (cannot get property 'get' of undefined).

因此解决方法是在 FooService 中添加一个构造函数,如下所示:

So the fix is to add a constructor in FooService like this:

constructor(api: ApiService) {
    super(api);
}

但是问题在于它不是对开发人员友好的,什么也没有告诉您这样做,并且由于 FooService 扩展了 ModelService ,因此它应该具有相同的构造函数,因此具有相同的依赖关系

But problem is that it's not dev-friendly, nothing tells you to do so and since FooService extends ModelService, it should have the same constructor and therefore the same dependencies.

有什么方法可以继承依赖项吗?

Is there any way to inherit dependency?

PS:我已经尝试将 @Injectable()添加到 ModelService ,同样的错误.

PS: I already tried to add @Injectable() to ModelService, same error.

tsconfig.json :

{
  "compilerOptions": {
    "baseUrl": "",
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [
      "es6",
      "dom"
    ],
    "mapRoot": "./",
    "module": "es6",
    "moduleResolution": "node",
    "outDir": "../dist/out-tsc",
    "sourceMap": true,
    "target": "es5",
    "typeRoots": [
      "../node_modules/@types"
    ]
  }
}

package.json :

"dependencies": {
    "@angular/common": "2.2.1",
    "@angular/compiler": "2.2.1",
    "@angular/core": "2.2.1",
    "@angular/forms": "2.2.1",
    "@angular/http": "2.2.1",
    "@angular/platform-browser": "2.2.1",
    "@angular/platform-browser-dynamic": "2.2.1",
    "@angular/router": "3.2.1",
    ...
    ...
  },
  "devDependencies": {
    "@angular/compiler-cli": "2.2.1",
    ... 
    ...
  }

推荐答案

对于不引入额外依赖项并且不需要自己的构造函数的子类,

For child class that doesn't introduce extra dependencies and doesn't need its own constructor it is

@Injectable()
export abstract class ModelService<T> {...}

export class FooService extends ModelService<Foo>{

}

父类需要

@Injectable()装饰器(如果它使用类型注释而不是 @Inject ).子类不需要 @Injectable()装饰器.

@Injectable() decorator is needed for parent class (if it uses type annotation and not @Inject). No @Injectable() decorator is needed for child class.

对于可能具有自己的依赖项并因此需要自己的构造函数的子类,应将依赖项显式传递给 super (请参见其他答案).在JavaScript中,可以使用rest运算符和 @Inject 跳过某些重言式,但是对于TypeScript,可以安全地显式枚举所有构造函数参数.

For children classes that may have their own dependencies and thus need own constructors the dependencies should be explicitly passed to super (see the other answer). In JavaScript, rest operator and @Inject may be used to skip some tautology, but for TypeScript it is safe to enumerate all constructor parameters explicitly.

这篇关于继承依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆