ブートストラップで@Injectable
サービスが定義されています。コンストラクター注入を使用せずにサービスのインスタンスを取得したい。 ReflectiveInjector.resolveAndCreate
を使用してみましたが、新しいインスタンスが作成されるようです。
私がやろうとしている理由は、多くのコンポーネントから派生した基本コンポーネントがあるからです。ここで、サービスにアクセスする必要がありますが、派生コンポーネントのすべてにサービスを注入したくないので、それをctorに追加したくありません。
TLDR:ServiceLocator.GetInstance<T>()
が必要です
UPDATE:RC5 +のコードを更新: コンポーネントで使用するインジェクターインスタンスを保存
はい、ReflectiveInjector.resolveAndCreate()
は新しい未接続のインジェクターインスタンスを作成します。
Angulars Injector
インスタンスを注入し、それから目的のインスタンスを取得できます
constructor(private injector:Injector) {
injector.get(MyService);
}
Injector
をグローバル変数に保存し、このインジェクターインスタンスを使用して、たとえば https://github.com/angular/angular/issues/4112#issuecomment -153811572
NgModuleが使用される更新されたAngularでは、コード内の任意の場所で利用可能な変数を作成できます。
export let AppInjector: Injector;
export class AppModule {
constructor(private injector: Injector) {
AppInjector = this.injector;
}
}
別のアプローチでは、カスタムデコレータ(CustomInjectable
を定義して、依存性注入のメタデータを設定します。
export function CustomComponent(annotation: any) {
return function (target: Function) {
// DI configuration
var parentTarget = Object.getPrototypeOf(target.prototype).constructor;
var parentAnnotations = Reflect.getMetadata('design:paramtypes', parentTarget);
Reflect.defineMetadata('design:paramtypes', parentAnnotations, target);
// Component annotations / metadata
var annotations = Reflect.getOwnMetadata('annotations', target);
annotations = annotations || [];
annotations.Push(annotation);
Reflect.defineMetadata('annotations', annotations, target);
}
}
独自のコンストラクタではなく、親コンストラクタのメタデータを活用します。子クラスで使用できます:
@Injectable()
export class SomeService {
constructor(protected http:Http) {
}
}
@Component()
export class BaseComponent {
constructor(private service:SomeService) {
}
}
@CustomComponent({
(...)
})
export class TestComponent extends BaseComponent {
constructor() {
super(arguments);
}
test() {
console.log('http = '+this.http);
}
}
詳細については、この質問を参照してください。