web-dev-qa-db-ja.com

Angular 2依存関係をコンストラクタの外に注入する

私は現在、Angular 2.でDIを掘り下げています。次のような具象データ型の汎用サブタイプを使用してRESTクライアントを実装しています。

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間で共有される1つの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();

コードの重複を減らし、TypeScriptのジェネリックの問題を回避するために、引数なしのままにしたいコンストラクターに渡さずに、RESTConfigurationの1つのシングルトンインスタンスをRESTServiceクラスに挿入する方法を考えています。

上記の例(最初のコードスニペット)では、構成のカスタムインスタンスを提供する、作成したReflectiveInjectorを使用して構成を注入しようとしています。

私はいくつかの解決策について考えました:

  1. サービスまたはいくつかの静的クラスプロパティを使用してアプリの「グローバルインジェクター」にアクセスできるようにすることで、アプリにアクセスする

  2. 構成に追加のシングルトンロジックを実装する

  3. コンストラクターの外で角度ネイティブ注入メソッドを使用する方法を見つけていますか?

私の考えに間違いはありますか、それともDIフレームワークを誤用していますか?

14
hakkurishian

これはこの問題の解決策を提供するはずですが、コンストラクタパラメータとして提供せずにサービスを注入する必要がある場合にも役立ちます。

私は別の投稿でこの答えを見ました: コンポーネントで使用するためのインジェクターインスタンスの保存

Angular InjectorをAppModuleクラスで構成し、他のクラスで使用できます(任意のクラスから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;
    }
}

次に、他のクラスで次のことを実行できます(この質問では、MyServiceをHttpに置き換えます)。

@Injectable()
export class MyClass{
    private myService;

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

これは次のものを使用することと同等です。

constructor(private myService: MyService){}
26
ronenmiller