简体   繁体   English

Angular 6 服务:providIn: 'root' vs CoreModule

[英]Angular 6 Services: providedIn: 'root' vs CoreModule

With Angular 6, below is the preferred way to create singleton services:使用 Angular 6,以下是创建单例服务的首选方式:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class UserService {
}

From Angular doc: When you provide the service at the root level, Angular creates a single, shared instance of HeroService and injects into any class that asks for it.来自 Angular 文档:当您在根级别提供服务时,Angular 创建一个单一的 HeroService 共享实例,并注入到任何需要它的类中。 Registering the provider in the @Injectable metadata also allows Angular to optimize an app by removing the service if it turns out not to be used after all.在 @Injectable 元数据中注册提供者还允许 Angular 通过删除服务来优化应用程序,如果它最终没有被使用。

Also,还,

providers: [
    // no need to place any providers due to the `providedIn` flag...
  ]

So, does that mean we no more need CoreModule ?那么,这是否意味着我们不再需要CoreModule 了 We can import services and other common modules directly into AppModule.我们可以将服务和其他常用模块直接导入到 AppModule 中。

Well I would consider it as an alternative to creating a CoreModule, the documentation clearly states:好吧,我将其视为创建 CoreModule 的替代方案,文档明确指出:

There are two ways to make a service a singleton in Angular: Declare root for the value of the @Injectable() providedIn property在 Angular 中有两种方法可以使服务成为单例: 为 @Injectable() providedIn 属性的值声明根

Include the service in the AppModule or in a module that is only imported by the AppModule将服务包含在 AppModule 或仅由 AppModule 导入的模块中

I found this here Singleton Services doc我在这里找到了单例服务文档

If you app has a CoreModule of pure services you could simply get rid of it(if you don't think is necessary of course), although I don't recommend it, for me I consider it more mantainable to have a CoreModule because I can easily find it in the project and tells me what services are fundamental for the app and we need only one instance from them, instead of having to open a search dialog in the IDE and look for all the services that have the providedIn: 'root' setted.如果你的应用程序有一个 CoreModule 的纯服务,你可以简单地摆脱它(如果你认为当然没有必要),虽然我不推荐它,但对我来说,我认为拥有一个 CoreModule 更容易维护,因为我可以很容易地在项目中找到它并告诉我哪些服务是应用程序的基础,我们只需要它们的一个实例,而不必在 IDE 中打开一个搜索对话框并查找所有具有providedIn: 'root'设置。

我仍然会保留 CoreModule 用于一次性组件和 Http 拦截器,现在推荐使用providedIn属性来注册单例服务,为了清楚起见,我会将所有单例服务放在 core/services 目录下

That would be true if the CoreModule only contained services.如果 CoreModule 仅包含服务,那将是正确的。 However, it does include other things such as single use components.但是,它确实包括其他东西,例如一次性组件。

From Angular Docs:来自 Angular 文档:

Do gather application-wide, single use components in the CoreModule.在 CoreModule 中收集应用程序范围内的一次性组件。 Import it once (in the AppModule) when the app starts and never import it anywhere else.在应用程序启动时将其导入一次(在 AppModule 中),并且永远不要将其导入到其他任何地方。 (eg NavComponent and SpinnerComponent). (例如 NavComponent 和 SpinnerComponent)。

And what about interceptors and guards?拦截器和守卫呢? This things can be global I guess.我猜这件事可能是全球性的。 I agree with your consideration about CoreModule doesn't have declarations and only pure services, but I think Guards and Interceptors should be considerate too.我同意你对 CoreModule 没有声明而只有纯服务的考虑,但我认为 Guards 和 Interceptor 也应该考虑周到。

I think creating a core module became obsolete since a service can define itself to be registered to root via providedIn: root我认为创建核心模块已经过时了,因为服务可以定义自己以通过providedIn: root注册到providedIn: root

The (old!) angular style guide recommended to create a core module till v6: https://v6.angular.io/guide/styleguide建议在 v6 之前创建核心模块的(旧!)角度样式指南: https : //v6.angular.io/guide/styleguide

But since v7 there is no recommendation anymore to create a core module.但是从 v7 开始,不再建议创建核心模块。 I think it is exactly for that reason ( providedIn: root does the job).我认为正是出于这个原因( providedIn: root完成了这项工作)。

When Angular engine starts initiating a component, and you have declared services in your constructor, angular tries to pass the instances of the declared services to the component.当 Angular 引擎开始初始化一个组件,并且您在构造函数中声明了服务时,angular 会尝试将声明的服务的实例传递给组件。 So angular should somehow know where can be taken instances, there is a point where providers array comes.所以 angular 应该以某种方式知道可以在哪里获取实例,提供者数组有一个点。

When you declare needed services without providedin: core pair, we create non singleton instance of the service.当您在没有提供的情况下声明所需的服务时:核心对,我们创建服务的非单例实例。 which means that, when angular destroys component, services declared in the component will be destroyed too.这意味着,当 angular 销毁组件时,组件中声明的服务也将被销毁。

As mentioned before, there are two ways to declare application level singleton services: 1. declare them into providers of related module;如前所述,应用层单例服务的声明方式有两种: 1. 将其声明为相关模块的提供者; 2. declare them into providers of a component with providedIn: core pair. 2. 使用providedIn: 核心对将它们声明为组件的提供者。

also interesting note about @Injectable decorator.还有关于@Injectable 装饰器的有趣说明。 this is only required when service injects another service.这仅在服务注入另一个服务时才需要。 for example if you inject http service in your service, you have to add @Injecrable decorator.例如,如果您在服务中注入 http 服务,则必须添加 @Injecrable 装饰器。

this is how dependency injection works.这就是依赖注入的工作原理。

provideIn: root this could be useful in those scenarios where you have multi-application projects. provideIn: root这在您拥有多应用程序项目的情况下可能很有用。 In such kind of scenarios, you have an angular workspace with multiple projects inside it.在这种情况下,您有一个包含多个项目的角度工作区。

And, you would never want your project to have some kind of dependencies on the workspace's core module as it won't allow you to run your project independently.而且,您永远不会希望您的项目对工作区的core module有某种依赖关系,因为它不允许您独立运行您的项目。

In such a case, you keep your services in the library and use providedIn: 'root' for making them singleton.在这种情况下,您将服务保留在库中并使用providedIn: 'root'使它们成为单例。

  • providedIn: 'root' is the declarative way providedIn: 'root'是声明方式
  • core module is the imperative way core module是命令式的方式

If you need to conditionally inject providers, it is easy to do it within a module, and the core module is the one importing every mandatory service for your app.如果你需要有条件地注入提供者,在一个模块中很容易做到, core module是为你的应用程序导入所有必需服务的core module This is useful for instance to import testing or production services depending on an environment variable.例如,这对于根据环境变量导入测试或生产服务很有用。

If you do have only one version for your service, then providedIn: 'root' is a good to go.如果您的服务只有一个版本,那么providedIn: 'root'是一个不错的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM