Treeshakable Providers

Treeshakable Providers

Providing the service within the scope of the lazy loaded module.

As you all know there are two ways to register/provide a service to an Angular dependency injector.

  1. The providers-array of the @NgModule decorater

  2. Treeshakable providers provided by the @Injectable decorater

With both ways you can achieve the same results but in the second way you
will have the benefit of treeshaking.
Treeshaking means in short that not referenced services within your codebase are 'treeshaked' and will not be included in the build-ouput (bundle).

Within the Angular DI system the services are provided to an injector.
If you create an service with the Angular CLI the service is provided in the
`root`-injector.

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

So far so good...
But how does it work together with lazy loaded modules?

As you all know lazy loaded modules create a separate injector below the root-injector.

And this brings us to the idea to limit the scope of the service only to this lazy loaded module.

Something like this:

@Injectable({
  providedIn: MyLazyLoadModule,
})
export class MyLazyService{
}

The idea makes sense but still it causes a circular reference!

ReferenceError: Cannot access 'MyLazyLoadModule' before initialization

This situation looks in a diagram expressed like this.
You can see the references in a circle.

To solve this problem you can create a kind of an container-module and import it
within the MyLazyLoadModule.

The diagram looks then like this:

BAM!

Now the error should be gone and your service is now only loaded by requesting the lazy loaded module.
But also note that the service is only visible in the lazy loaded module context.