dst*_*str 59 angular2-injection angular2-di angular
我@Injectable在bootstrap中定义了一个服务.我想在不使用构造函数注入的情况下获取服务的实例.我试过使用ReflectiveInjector.resolveAndCreate但似乎创建了一个新实例.
我试图做的原因是我有一个由许多组件派生的基本组件.现在我需要访问服务,但我不想将它添加到ctor,因为我不想在所有衍生组件上注入服务.
TLDR:我需要一个 ServiceLocator.GetInstance<T>()
更新: RC5 +的更新代码:存储用于组件的进样器实例
Gün*_*uer 58
是的,ReflectiveInjector.resolveAndCreate()创建一个新的未连接的注入器实例.
您可以使用注入Angulars Injector实例并从中获取所需的实例
constructor(private injector:Injector) {
injector.get(MyService);
}
Run Code Online (Sandbox Code Playgroud)
您还可以存储Injector一些全局变量,然后使用此注入器实例来获取提供的实例,例如https://github.com/angular/angular/issues/4112#issuecomment-153811572中所述.
小智 29
在使用ngModules的更新的Angular中,您可以在代码中的任何位置创建可用的变量:
export let AppInjector: Injector;
export class AppModule {
constructor(private injector: Injector) {
AppInjector = this.injector;
}
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是定义一个自定义装饰器(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);
}
}
Run Code Online (Sandbox Code Playgroud)
它将利用来自父构造函数的元数据,而不是其自身的元数据。您可以在子类上使用它:
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,请参见此问题:
Angular 14 引入了一个inject函数。
根据文档
实际上,在构造函数、构造函数参数和字段初始值设定项中允许调用inject():
@Injectable({providedIn: 'root'})
export class Car {
radio: Radio|undefined;
// OK: field initializer
spareTyre = inject(Tyre);
constructor() {
// OK: constructor body
this.radio = inject(Radio);
}
}
Run Code Online (Sandbox Code Playgroud)
和
从提供者的工厂调用注入也是合法的:
providers: [
{provide: Car, useFactory: () => {
// OK: a class factory
const engine = inject(Engine);
return new Car(engine);
}}
]
Run Code Online (Sandbox Code Playgroud)
因此,在您的情况下,您可以使用
class MyClass {
serviceLocator = inject(ServiceLocator)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
46629 次 |
| 最近记录: |