typescript Angular 2 在构造函数之外注入依赖

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39101865/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:46:57  来源:igfitidea点击:

Angular 2 Inject Dependency outside Constructor

angulartypescriptdependency-injectionsingleton

提问by hakkurishian

I am currently digging into DI in Angular 2. I'm implementing a REST-Client using a generic subtypes for concrete Datatypes like this:

我目前正在 Angular 2 中深入研究 DI。我正在使用通用子类型来实现一个 REST-Client,具体数据类型如下:

class RESTClient<T>{
    constructor() {
        var inj =  ReflectiveInjector.resolveAndCreate([HTTP_PROVIDERS]);
        this.http = inj.get(Http);
        this.conf = RESTConfiguration;
    }
}
class BookClient extends RESTClient<Book>{      
    constructor(){
        // since I dont want to inject the HTTP Providers here, I'm using a custom    injector in the super class
        super();
    }
}

class WriterClient extends RESTClient<Writer>{      
    ...
    ...
}

So as I understand, there will be one http service shared between all RESTClients injected by the superclasses REST-Service.

因此,据我所知,超类 REST-Service 注入的所有 RESTClient 之间将共享一个 http 服务。

Now I want to have a RESTConfiguration class as such:

现在我想要一个 RESTConfiguration 类:

@Injectable()
export class RESTConfiguration {
    get baseURL() {
     return this._baseURL;
    }

    set baseURL(value) {
        alert("sets value to"+value);
        this._baseURL = value;
    }

    private _baseURL;

}

It should be configured in the main app as such:

它应该在主应用程序中配置如下:

initializeApp(){
  this.restconf.baseURL = "http://localhost:3004/";
}
bootstrap(MyApp, [RESTConfiguration]).then();

I'm now wondering how to inject one singleton instance of my RESTConfiguration into the RESTService class without passing it to the constructor which I want to remain argument-less in order to reduce code duplication and avoid issues with generics in typescript.

我现在想知道如何将我的 RESTConfiguration 的一个单例实例注入到 RESTService 类中,而不将它传递给我希望保持无参数的构造函数,以减少代码重复并避免打字稿中的泛型问题。

In the above example (first code snippet) I'm trying to inject my configuration using the ReflectiveInjector I created which delivers me a custom instance of my Configuration.

在上面的示例(第一个代码片段)中,我尝试使用我创建的 ReflectiveInjector 注入我的配置,该 ReflectiveInjector 为我提供了我的配置的自定义实例。

I thought about several solutions:

我想了几个解决方案:

  1. Getting access to the Apps "global injector" by making one available using a service or some static class property

  2. Implementing extra singleton-logic into my configuration

  3. finding a way to use the angular-native injection method outside of the constructor?

  1. 通过使用服务或某些静态类属性使应用程序可用来访问应用程序“全局注入器”

  2. 在我的配置中实现额外的单例逻辑

  3. 找到一种在构造函数之外使用 angular-native 注入方法的方法?

Are there mistakes in my thinking or am I misusing the DI framework ?

我的想法有错误还是我滥用了 DI 框架?

回答by ronenmiller

This should provide a solution for this issue but also help in any case where one needs to inject a service without supplying it as a constructor parameter.

这应该为这个问题提供一个解决方案,但在需要注入服务而不将其作为构造函数参数提供的任何情况下也有帮助。

I saw this answer in another post: Storing injector instance for use in components

我在另一篇文章中看到了这个答案: Storing injector instance for use in components

You can configure the Angular Injector in your AppModule class, and then use it in any other class (you can access AppModule's members from any class).

您可以在 AppModule 类中配置 Angular Injector,然后在任何其他类中使用它(您可以从任何类访问 AppModule 的成员)。

In AppModule add:

在 AppModule 中添加:

export class AppModule { 
  /**
     * Allows for retrieving singletons using `AppModule.injector.get(MyService)`
     * This is good to prevent injecting the service as constructor parameter.
     */
    static injector: Injector;
    constructor(injector: Injector) {
        AppModule.injector = injector;
    }
}

Then in your other class you can do the following (for this question replace MyService with Http):

然后在您的其他课程中,您可以执行以下操作(对于此问题,请将 MyService 替换为 Http):

@Injectable()
export class MyClass{
    private myService;

    constructor(){
        this.myService = AppModule.injector.get(MyService);
    }
}

This would be equivalent to using:

这相当于使用:

constructor(private myService: MyService){}