Cod*_*n25 3 dependency-injection angular-services angular-module angular
@Injectable() 装饰器中“root”中提供的服务是否仍然必须位于模块的提供者数组中?
Angular文档并没有真正给我答案,或者我不太理解它。
在我的核心文件夹中,我有一个在根目录中提供的身份验证服务。我不想将我的核心模块导入到应用程序模块中,以便使用提供的所有服务和组件。
我是否必须在模块的提供者数组中另外设置服务,或者已经使用装饰器在根级别提供该服务就足够了吗?
您提供的链接中的要点是注册服务的所有不同方法,从最不具体到最具体。
应用程序特定 - 使用@Injectable({ providedIn: 'root' })
当您在根级别提供服务时,Angular 会创建 HeroService 的单个共享实例,并将其注入到任何需要它的类中。在 @Injectable() 元数据中注册提供程序还允许 Angular 通过从编译的应用程序中删除不使用的服务来优化应用程序。
特定于模块 - 在模块提供程序中注册
当您向特定 NgModule 注册提供程序时,该 NgModule 中的所有组件都可以使用同一个服务实例。要在此级别注册,请使用@NgModule()装饰器的providers属性,
组件特定 - 在组件中注册
当您在组件级别注册提供程序时,您会通过该组件的每个新实例获得该服务的一个新实例。在组件级别,在@Component()元数据的providers属性中注册服务提供者。
以上所有引用均来自官方服务和依赖注入简介页面
@Injectable默认的 CLI 方法更容易。我认为大多数用例都属于前两种方法。
提示:只需使用providedIn: 'root'. 如果由于树抖动而未使用模块,则不会为模块编译未使用的服务。声明特定于模块的服务似乎是多余的,并且正如我们将看到的,可能会导致问题。
有两种方法可以注册特定于模块的服务 - 从模块或从服务。
模块
@NgModule({
providers: [MyService]
})
export class MyModule {}
Run Code Online (Sandbox Code Playgroud)
服务
@Injectable({ providedIn: MyModule })
Run Code Online (Sandbox Code Playgroud)
后者是官方推荐的方法。声明提供者数组是早期的遗留问题。
来自文档:
上面的示例显示了在模块中提供服务的首选方式。此方法是首选方法,因为如果没有任何注入,它可以对服务进行树摇动。如果无法在服务中指定哪个模块应提供该服务,您还可以在模块内声明该服务的提供者
providedIn: 'root'所以我们看到这种方法是可以摇树的。到目前为止,一切都很好。但是,如果您只是尝试导入声明使用客户端的组件的同一模块,最终会出现循环引用。
采取这样的设置:
我的模块
declarations: [
MyComponent
]
Run Code Online (Sandbox Code Playgroud)
我的服务
@Injectable({ providedIn: MyModule })
Run Code Online (Sandbox Code Playgroud)
我的组件
constructor(private myService: MyService) {}
Run Code Online (Sandbox Code Playgroud)
存在循环依赖。
解决方法是创建一个服务模块并将其导入到您的模块中。
我的模块
imports: [
MyModuleServices
],
declarations: [
MyComponent
]
Run Code Online (Sandbox Code Playgroud)
我的模块服务
Run Code Online (Sandbox Code Playgroud)
我的服务
@Injectable({ providedIn: MyModuleServices })
Run Code Online (Sandbox Code Playgroud)
我的组件
constructor(private myService: MyService) {}
Run Code Online (Sandbox Code Playgroud)
这是一个非常冗长的替代方案,而不是简单地使用providedIn: 'root'并让 Tree Shaking 来完成工作。
| 归档时间: |
|
| 查看次数: |
4199 次 |
| 最近记录: |