Skip to content

Commit

Permalink
chore(core): address review comments - 04/08/2019
Browse files Browse the repository at this point in the history
  • Loading branch information
raymondfeng committed Apr 8, 2019
1 parent 5e86bc3 commit 56fa565
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 20 deletions.
25 changes: 17 additions & 8 deletions docs/site/Creating-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@ import {MyValueProvider} from './providers/my-value.provider';
import {Component} from '@loopback/core';

export class MyComponent implements Component {
constructor() {
this.controllers = [MyController];
this.providers = {
'my-value': MyValueProvider,
};
this.classes = {
'my-validator': MyValidator,
};
servers = {
'my-server': MyServer,
};
lifeCycleObservers = [MyObserver];
controllers = [MyController];
providers = {
'my-value': MyValueProvider,
};
classes = {
'my-validator': MyValidator,
};

constructor() {
// Set up `bindings`
const bindingX = Binding.bind('x').to('Value X');
const bindingY = Binding.bind('y').toClass(ClassY);
this.bindings = [bindingX, bindingY];
Expand Down Expand Up @@ -57,6 +62,8 @@ class is created and then:
- Each Class is bound to its key in `classes` object via
`app.bind(key).toClass(cls)`
- Each Binding is added via `app.add(binding)`
- Each Server class is registered via `app.server()`
- Each LifeCycleObserver class is registered via `app.lifeCycleObserver()`

Please note that `providers` and `classes` are shortcuts for provider and class
`bindings`.
Expand All @@ -68,6 +75,8 @@ create the following bindings in the application context:
- `my-validator` -> `MyValidator` (class)
- `x` -> `'Value X'` (value)
- `y` -> `ClassY` (class)
- `my-server` -> `MyServer` (server)
- `lifeCycleObservers.MyObserver` -> `MyObserver` (life cycle observer)

## Providers

Expand Down
17 changes: 13 additions & 4 deletions docs/site/Extension-life-cycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ permalink: /doc/en/lb4/Extension-life-cycle.html

As described in [Life cycle](Life-cycle.md), a LoopBack
[Application](Application.md) has its own life cycles at runtime. Corresponding
events such as `start` and `stop` are emitted upon the state change.
events such as `start` and `stop` are emitted upon the state change. Please note
that LoopBack only support `start` and `stop` events for an application's life
cycles at this moment.

Extension modules for LoopBack often contribute artifacts such as servers,
datasources, and connectors to the application. They typically provide a
Expand All @@ -24,7 +26,8 @@ register life cycle observers.
### Implement a life cycle observer

A life cycle observer class optionally implements `start` and `stop` methods to
be invoked upon `start` and `stop` events.
be invoked upon `start` and `stop` events emitted by an application's life cycle
respectively.

```ts
import {LifeCycleObserver} from '@loopback/core';
Expand Down Expand Up @@ -62,10 +65,16 @@ tag - `CoreTags.LIFE_CYCLE_OBSERVER`.
app.lifeCycleObserver(MyObserver);
```

Life cycle observers can be registered via a component too:
Life cycle observers can be declared via a component class too. when the
component is mounted to an application, the observers are automatically
registered.

```ts
export class MyComponentWithObservers {
export class MyComponentWithObservers implements Component {
lifeCycleObservers = [XObserver, YObserver];
}

// Mount the component
app.mount(MyComponentWithObservers);
// Now `XObserver` and `YObserver` are registered in the application.
```
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,25 @@

import {LifeCycleObserver} from '@loopback/core';

/**
* An mock-up `LifeCycleObserver`. Please note that `start` and `stop` methods
* can be async or sync.
*/
export class MyLifeCycleObserver implements LifeCycleObserver {
status = '';

/**
* Handling `start` event asynchronously
*/
async start() {
// Perform some work asynchronously
// await startSomeAsyncWork(...)
this.status = 'started';
}

/**
* Handling `stop` event synchronously.
*/
stop() {
this.status = 'stopped';
}
Expand Down
1 change: 0 additions & 1 deletion packages/cli/generators/observer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ module.exports = class ObserverGenerator extends ArtifactGenerator {
}

_setupGenerator() {

this.option('group', {
description: 'Name of the observer group for ordering',
required: false,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export class Application extends Context implements LifeCycleObserver {
namespace: CoreBindings.LIFE_CYCLE_OBSERVERS,
type: CoreTags.LIFE_CYCLE_OBSERVER,
defaultScope: BindingScope.SINGLETON,
}).tag(CoreTags.LIFE_CYCLE_OBSERVER);
}).apply(asLifeCycleObserver);
this.add(binding);
return binding;
}
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
Constructor,
ValueOrPromise,
} from '@loopback/context';
import {CoreBindings, CoreTags} from './keys';
import {CoreTags} from './keys';

/**
* Observers to handle life cycle start/stop events
Expand Down Expand Up @@ -49,13 +49,13 @@ export function isLifeCycleObserverClass(
}

/**
* Configure the binding as life cycle observer
* @param binding Binding
* A `BindingTemplate` function to configure the binding as life cycle observer
* by tagging it with `CoreTags.LIFE_CYCLE_OBSERVER`.
*
* @param binding Binding object
*/
export function asLifeCycleObserver<T = unknown>(binding: Binding<T>) {
return binding
.tag(CoreTags.LIFE_CYCLE_OBSERVER)
.tag({namespace: CoreBindings.LIFE_CYCLE_OBSERVERS});
return binding.tag(CoreTags.LIFE_CYCLE_OBSERVER);
}

/**
Expand Down

0 comments on commit 56fa565

Please sign in to comment.