Skip to content

Commit

Permalink
docs: add Injectable migration docs (angular#32581)
Browse files Browse the repository at this point in the history
PR Close angular#32581
  • Loading branch information
kapunahelewong authored and mhevery committed Oct 11, 2019
1 parent 64fd0d6 commit c88305d
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -845,6 +845,8 @@ testing/** @angular/fw-test
/aio/content/guide/migration-renderer.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/migration-undecorated-classes.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/migration-dynamic-flag.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/migration-injectable.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes



# ================================================
Expand Down
10 changes: 8 additions & 2 deletions aio/content/guide/deprecations.md
Expand Up @@ -361,10 +361,16 @@ See the [dedicated migration guide for Renderer](guide/migration-renderer).

{@a undecorated-classes}
### Migrating undecorated classes
See the [dedicated migration guide for undecorated classes](guide/migration-undecorated-classes).

See the [dedicated migration guide for undecorated classes](guide/migration-undecorated-classes).

{@a injectable}
### Adding missing `@Injectable()` decorators

See the [dedicated migration guide for adding missing `@Injectable` decorators](guide/migration-injectable).

{@a flag-migration}
### Dynamic queries flag migration
### Migrating dynamic queries

See the [dedicated migration guide for dynamic queries](guide/migration-dynamic-flag).

Expand Down
86 changes: 86 additions & 0 deletions aio/content/guide/migration-injectable.md
@@ -0,0 +1,86 @@
# Migration to Add Missing `@Injectable()` Decorators

## What does this schematic do?

This schematic adds an `@Injectable()` decorator to a class
if the class has been added as a provider anywhere in the application.

An example diff might look like the following:

**Before:**

```ts
export class TypeCase {...}
```

**After:**

```ts
@Injectable()
export class TypeCase {...}
```


There are a few cases where the decorator won't be added. For example:

- It already has another decorator such as `@Component()`, `@Directive()` or `@Pipe()`. These decorators already cause the compiler to generate the necessary information.
- The provider definition has `useValue`, `useFactory`, or `useExisting`. In
these cases, the framework doesn't need the `@Injectable()` decorator to create the class because
because it can just use the value,
factory function, or existing instance that was provided.

For example, for the following module definition, the schematic will check
`TypeCase`, `ProvideCase`, `ExistingClass`, and `SomeClass` to ensure they
are marked with the `@Injectable()` decorator and add one if not.


```ts
@NgModule({
providers: [
// TypeCase needs @Injectable()
TypeCase,
// ProvideCase needs @Injectable()
{provide: ProvideCase},
// No @Injectable() needed because the value will be used
{provide: ValueCase, useValue: 0},
// No @Injectable() needed because factory will be used
{provide: FactoryCase, useFactory: ()=> null},
// ExistingClass needs @Injectable()
{provide: ExistingToken, useExisting: ExistingClass},
// SomeClass needs @Injectable()
{provide: ClassToken, useClass: SomeClass},
// No @Injectable() needed because it has a @Pipe() decorator
PipeCase,

]
})

```


## Why is this migration necessary?

In our docs, we've always recommended adding `@Injectable()`
decorators to any class that is provided or injected in your application.
However, older versions of Angular did allow injection of a class
without the decorator in certain cases, such as AOT mode.
This means if you accidentally omitted the decorator, your application
may have continued to work despite missing `@Injectable()` decorators in some places.
This is problematic for future versions of Angular. Eventually, we plan
to strictly require the decorator because doing so enables further
optimization of both the compiler and the runtime. This schematic
adds any `@Injectable()` decorators that may be missing to future-proof your app.



## When should I be adding `@Injectable()` decorators to classes?

Any class that is provided or injected somewhere must have an `@Injectable()` decorator. The decorator is necessary for the framework to properly create an instance of that class through DI.

However, as noted above, classes that already have another class decorator like `@Pipe` do not need both decorators. The existing class decorator will cause the compiler to generate the proper information.


## Should I update my library?

Yes, if your library has any tokens that are meant to be injected, they should be updated with the `@Injectable()` decorator. In a future version of Angular, a missing `@Injectable()` decorator will always throw an error.

0 comments on commit c88305d

Please sign in to comment.