确保实例化服务

Ben*_*ing 8 dependency-injection angular-services angular

背景

我们正在构建一个Angular2应用程序,并且正在积累与一个模块相关的许多特定服务.所有这些服务都松散地耦合到Subject<Type>应用程序中的事件系统.

通过构造函数实例化

因为这些服务永远不会被直接引用,只能订阅事件,所以我们只需要以某种方式实例化它们.目前我们只是将它们注入到另一个使用的服务的构造函数中.

// Services not used, just to make sure they're instantiated
constructor(
  private appService1: AppService1,     
  private appService2: AppService2,
  private appService3: AppService3,
  ...
){ }
Run Code Online (Sandbox Code Playgroud)

这看起来有点像黑客,是否有更好的方法来显式声明需要实例化的服务而不通过构造函数注入它们?

Ale*_*mov 8

确保根据您的偏好实例化服务的另一种方式是将其注入模块构造函数中

这样,服务将与模块一起实例化。

因此,与其像问题中描述的那样创建一个全新的服务,而不仅仅是为了向其中注入其他服务,不如做这样的事情:

@NgModule ({
    ...
})
export class SomeModule {
    // Services are not used, just to make sure they're instantiated
    constructor(
        private appService1: AppService1,     
        private appService2: AppService2,
        private appService3: AppService3) {
    }
}
Run Code Online (Sandbox Code Playgroud)

与该方法相比,该useValue: new AppService1()方法至少具有2个好处。

第一个也是显而易见的一个,如果AppService1具有依赖关系,它们将由Angular的DI自动解决。

第二,通常在应用程序中未实际引用的服务是全局配置服务中的王者。因此,您可以在单个源文件中将此类服务实例与全局配置结合在一起。这是一个例子。在这种情况下,这是NgbDatepickerConfig服务:

import { NgModule } from "@angular/core";

import {
    NgbDateAdapter, NgbDateNativeUTCAdapter, NgbDateParserFormatter, NgbDatepickerConfig, NgbDatepickerModule,
    NgbDropdownModule, NgbTabsetModule
} from "@ng-bootstrap/ng-bootstrap";

import { UsDateParserFormatter } from "./us-date-parser-formatter";

@NgModule({
    exports: [
        NgbDatepickerModule,
        NgbDropdownModule,
        NgbTabsetModule
    ],
    providers: [
        { provide: NgbDateAdapter, useClass: NgbDateNativeUTCAdapter },
        { provide: NgbDateParserFormatter, useClass: UsDateParserFormatter }
    ]
})
export class NgbImportsModule {
    public constructor(private readonly datepickerConfigService: NgbDatepickerConfig) {
        datepickerConfigService.minDate = { year: 1900, month: 1, day: 1 };
        datepickerConfigService.maxDate = { year: 2099, month: 12, day: 31 };
    }
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,NgbImportsModule最初只是为了将所需模块从NGB重新导出到我的应用程序的其余部分而引入的。但是随着我的应用程序功能的建立,它NgbImportsModule变成了一个地方,可在一个地方方便地配置NGB的某些部分。