Skip to content

Commit

Permalink
docs: polish Dependency Injection article
Browse files Browse the repository at this point in the history
  • Loading branch information
bajtos committed Mar 27, 2018
1 parent f94f6a1 commit 6105cd5
Showing 1 changed file with 23 additions and 10 deletions.
33 changes: 23 additions & 10 deletions docs/site/Dependency-injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ resolving their dependencies as needed.
In this particular example, the class is a
[Provider](Writing-Components#providers). Providers allow you to customize the
way how a value is created by the Context, possibly depending on other Context
values. A provider is typically bound using `.toProvider(.md)` API:
values. A provider is typically bound using `.toProvider()` API:

```js
app.bind('authentication.provider').toProvider(AuthenticationProvider);
Expand Down Expand Up @@ -149,7 +149,8 @@ default.

```ts
class InfoController {
@inject('logger') private logger = ConsoleLogger();
@inject('logger', {optional: true})
private logger = ConsoleLogger();

status() {
this.logger.info('Status endpoint accessed.');
Expand Down Expand Up @@ -202,26 +203,28 @@ export class LoggerProvider implements Provider<Logger> {
```

Optional dependencies can also be used with constructor and method injections.
For example:

An example showing optional constructor injection in action:

```ts
// Optional constructor injection
export class LoggerProvider implements Provider<Logger> {
constructor(
// Log writer is an optional dependency and it falls back to `logToConsole`
@inject('log.writer', {optional: true})
private logWriter: LogWriterFn = logToConsole,

// Log level is an optional dependency with a default value `WARN`
@inject('log.level', {optional: true})
private logLevel: string = 'WARN',
) {}
}
```

An example of optional method injection, where the `prefix` argument is
optional:

```ts
// Optional method injection
export class MyController {
// prefix is optional
greet(
@inject('hello.prefix', {optional: true})
prefix: string = 'Hello',
Expand All @@ -234,7 +237,9 @@ export class MyController {
## Circular dependencies

LoopBack can detect circular dependencies and report the path which leads to the
problem. For example,
problem.

Consider the following example:

```ts
import {Context, inject} from '@loopback/context';
Expand Down Expand Up @@ -277,12 +282,20 @@ try {
context.getSync('lead');
} catch (e) {
console.error(e.toString());
// Error: Circular dependency detected: lead --> @DeveloperImpl.constructor[0]
// --> team --> @TeamImpl.constructor[0] --> project --> @ProjectImpl.constructor[0]
// --> lead
}
```

When the user attempts to resolve "lead" binding, LoopBack detects a circular
dependency and prints the following error:

```text
Error: Circular dependency detected:
lead --> @DeveloperImpl.constructor[0] -->
team --> @TeamImpl.constructor[0] -->
project --> @ProjectImpl.constructor[0] -->
lead
```

## Additional resources

- [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) on
Expand Down

0 comments on commit 6105cd5

Please sign in to comment.