Angular 8: 将 utils 服务定义为单例并使用静态方法?

Angular 8: Define a utils service as singleton and with static methods?

我目前从Angular 8开始。现在我想编写一个包含util函数的服务("CoreService")。但我想知道我到底应该怎么做,以及不同选项的优点或缺点是什么:

  1. 我应该定义为单例吗?
  2. 我应该将函数定义为静态方法(由 CoreService.doSomething() 调用)还是将其定义为具有非静态方法的可注入 class(在构造函数中注入)?

也许其中一个选项对性能(内存?)有或多或少的影响。

非常感谢任何回答!

再见The_Unknown

好的,让我们解决 Angular 中的服务。让我们先直接了解一些细节。

创建服务的推荐方法是使用 CLI:

ng generate service foo/weather

这将在 src/app/foo/weather.service.ts 下创建一个新服务 - 以及一些测试框架。如果您检查这段代码,您会发现它看起来像这样:

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

1.是否单身

现在看上面的 providedIn: 'root' 行。这样,您基本上是在说 Angular 应该在根级别提供此服务。在这种情况下,Angular 将创建一个单一的、共享的 WeatherService 实例,并将这个单一实例注入到任何需要它的组件中。此外,来自 Angular 文档:

Registering the provider in the @Injectable() metadata also allows Angular to optimize an app by removing the service from the compiled app if it isn't used.

所以这也可以为您节省一些带宽。

当然服务是供其他组件使用的。如果您决定在组件级别注册一个提供者,您将获得一个新的服务实例以及该组件的每个新实例。它将是这样的:

@Component({
  selector:    'app-cities',
  templateUrl: './cities.component.html',
  providers:  [ WeatherService ]
})

还有第三个 "level" 粒度 - 范围为一个模块 - 如果你想让你的服务实例可用于所有组件 只是在上述模块中:

@NgModule({
  providers: [
    WeatherService,
    AnotherService
  ],
  ...
})

简而言之 - 您可以控制您想要的服务方式 - 是否单身 - 以及所有的影响。

2。静态或实例方法

在我看来这不是一个真正的问题。要走的路是使用实例方法。无论如何,这是通过 Angular 的依赖注入强制执行的。您将创建的组件将请求您的服务实例。 Angular 的 DI 将提供一个(单例或新的),您可以像使用任何其他实例化对象一样使用它:

@Injectable({
  providedIn: 'root',
})
export class WeatherService {
  getTodaysTemperature() { return 7; }
}

@Component({
   ... // omitted for simplicity
})
export class TemperatureComponent {
  constructor(weatherService: WeatherService) {
      this.temperature = weatherService.getTodaysTemperature();
  }
}

所以只要确保你提供了相应的实例方法就可以了。测试也很好,因为您可以注入您的服务甚至模拟它。