Angular 2在构造函数外部注入依赖项

时间:2016-08-23 12:56:13

标签: angular typescript dependency-injection singleton

我目前正在深入研究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>{      
    ...
    ...
}

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

现在我希望有一个RESTConfiguration类:

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

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

    private _baseURL;

}

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

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

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

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

我想到了几个解决方案:

  1. 访问Apps&#34;全局注入器&#34;通过使用服务或某些静态类属性使其可用

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

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

  4. 我的想法是否存在错误,或者我滥用DI框架?

1 个答案:

答案 0 :(得分:22)

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

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

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

在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;
    }
}

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

@Injectable()
export class MyClass{
    private myService;

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

这相当于使用:

constructor(private myService: MyService){}