LoginSignup
0

More than 3 years have passed since last update.

Angularのproviderは何故modules.tsに定義するべきなのかをアンチパターンから学ぶ

Last updated at Posted at 2018-12-05

前置き

Angularの一般的な構成を見ると、app.modules.tsなどのNgModuleで定義するのが一般的です。
しかし、Componentでもprovidersを定義することは可能です。
何故Componentに定義せず、NgModuleで定義するべきなのかという問題を、開発時に遭遇したコードから考察します。

問題のコード

Component内でprovidersを定義していた時、以下のコードで問題が起きました。

heroes.component.ts
@Component({
  selector: 'app-heroes',
  templateUrl: 'foo.component.html',
  providers: [
    HeroService,
  ],
})
export class HeroesComponent {
heroes.component.spec.ts
beforeEach(() => {
  TestBed.configureTestingModule({
    declarations: [
      HeroesComponent,
    ],
    providers: [
      { provide: HeroService, useClass: MockHeroService },
    ],
  });
});

上記のように、テスト時にテストのために作成したモッククラス注入させようとした際にMockHeroServiceの注入をすることに失敗し、Mockの処理を走らせることができませんでした。
なぜ失敗したかというと、 HeroesComponent が見るHeroService はspecで定義したHeroService ではなく、 HeroesComponent で定義した HeroService を参照しにいくからです。

この例から分かるように、 HeroesComponentHeroService と切り離された関係でなくなり、独立性が損なわれることになります。

まとめ

今回の例から分かるように、Component内にprovidersをして依存性を注入してしまうと、アプリケーションという視点から見た時に関係性の分離ができていないため、DIの本質から逸脱しているというのは明白です。
なので、NgModuleで定義しましょうということです。

Angular 6

というのはAngular4までの話で、Angular6を利用している場合、 @InjectableprovidedIn を利用すれば、今回のような過ちは早々起きることもないかと思われます。

明日は、 @Kirika さんが担当します
よろしくお願いします

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0