Angular 2 Inject Dependency outside Constructor

2020-02-08 03:01发布

问题:

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

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.

Now I want to have a RESTConfiguration class as such:

@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.

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.

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?

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

回答1:

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

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).

In AppModule add:

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):

@Injectable()
export class MyClass{
    private myService;

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

This would be equivalent to using:

constructor(private myService: MyService){}