Angular 依赖注入框架里 useExisting 和 useClass 的使用场景

Angular 依赖注入框架里 useExisting 和 useClass 的使用场景

从上图能看出,所有注入的示例都通过factory方法返回,只是factory方法的实现有所差异。


As we can see in the picture above all of providers can be presented similar useFactory. When it’s the time to get an instance of provider angular just calls factory function.


一些例子:


{provide: Class1, useClass: Class1}

1

等价于:


Class1

1

而:


{provide: Class1, useClass: Class3}

1

you can configure, that when a constructor requests Class1 Angular DI creates an instance of Class3 and passes it to the constructor.


当构造函数的参数需要传入Class1时,Angular DI传入一个Class3的框实例到构造函数里。


而下面这个例子:


{provide: Class2, useExisting: Class2}

1

doesn’t result in an instance being created, but you can see this rather than an alias. If a constructor requests Class2, Angular DI looks for another provider for key Class2 and injects the instance from this Class2 provider. You can see useExisting like a reference to another provider or an alias.


当构造函数需要Class2时,Angular DI从另一个key为Class2的provider里查找,取出对应的实例进行注入。


Injectable and Provider are 2 different things. The injectable is a class DI can create an instance of, or a provided value that might be passed to a constructor. A provider is an entry in a registry of providers that DI maintains and that allows to lookup up providers by key (key is the type of a constructor parameter, a string or an InjectToken). The provider also holds information about how to “create” the injectable value/instance. DI looks up a provider, the provider provides the value, and DI passes the value (instance of an injectable or a value provided as-is) to a constructor.


Injectable和Provider是两个不同的概念。Injectable是一个class,Angular DI可以基于该class创建实例,或者DI可以提供一个值,能够传递到constructor里。DI内部维护了一个provider注册表,该注册表支持根据key查询provider.


Key is the type of a constructor parameter, a string or an InjectToken)


key是构造函数的参数,一个字符串或者InjectToken. Provider有足够的knowledge知道如何去创建一个value或者实例。


DI询问provider,provider提供值,DI将值传递到构造函数里。


If you register MyClass as provider, this is the short form of { provide: MyClass, useClass: MyValue } where provide: MyClass is the key a provider can be found with, and useClass: MyValue is a strategy passed to the provider that informs the provider what value it should provide for this key.


provide: MyClass是provider的key,Angular DI注册表里根据这个key找到provider.


useClass: MyValue, 一个传递给provider的strategy,告诉provider对于指定的key,应该提供何种value.


useClass: MyValue相当于"use new MyClass(…)"


useExisting: Foo


DI需要去查找key为Foo的provider,然后注入Foo provider提供的value.


看一些具体的例子。


UseExisting

Angular 依赖注入框架里 useExisting 和 useClass 的使用场景

在注入ServiceOldS时,使用ServiceNewS这个provider提供的值。

因此,运行时,old和newService两个实例指向的都是newService实例,都是ServiceNewS这个provider注入的实例:

Angular 依赖注入框架里 useExisting 和 useClass 的使用场景Angular 依赖注入框架里 useExisting 和 useClass 的使用场景Angular 依赖注入框架里 useExisting 和 useClass 的使用场景Angular 依赖注入框架里 useExisting 和 useClass 的使用场景The provide property holds the token that serves as the key for both locating a dependency value and configuring the injector.

别名提供者:useExisting

useExisting 提供了一个键,让你可以把一个令牌映射成另一个令牌。实际上,第一个令牌就是第二个令牌所关联的服务的别名,这样就创建了访问同一个服务对象的两种途径。


{ provide: MinimalLogger, useExisting: LoggerService }

1

useExisting 的作用

你可以使用别名接口来窄化 API。下面的例子中使用别名就是为了这个目的。


想象 LoggerService 有个很大的 API 接口,远超过现有的三个方法和一个属性。你可能希望把 API 接口收窄到只有两个你确实需要的成员。在这个例子中,MinimalLogger类-接口,就这个 API 成功缩小到了只有两个成员:


// Class used as a "narrowing" interface that exposes a minimal logger

// Other members of the actual implementation are invisible

export abstract class MinimalLogger {

 abstract logs: string[];

 abstract logInfo: (msg: string) => void;

}

1

2

3

4

5

6

消费代码:


@Component({

 selector: 'app-hero-of-the-month',

 templateUrl: './hero-of-the-month.component.html',

 // TODO: move this aliasing, `useExisting` provider to the AppModule

 providers: [{ provide: MinimalLogger, useExisting: LoggerService }]

})

export class HeroOfTheMonthComponent {

 logs: string[] = [];

 constructor(logger: MinimalLogger) {

   logger.logInfo('starting up');

 }

}

1=


HeroOfTheMonthComponent 构造函数的 logger 参数是一个 MinimalLogger 类型,在支持 TypeScript 感知的编辑器里,只能看到它的两个成员 logs 和 logInfo:Angular 依赖注入框架里 useExisting 和 useClass 的使用场景


上一篇:android好用的第三方库2018使用总结


下一篇:AM335x(TQ335x)学习笔记——触摸屏驱动编写