From ce395c63ee99977fa976efc6cb4ee27198a4406c Mon Sep 17 00:00:00 2001 From: shimks Date: Wed, 7 Feb 2018 14:22:59 -0500 Subject: [PATCH] feat(lb4): decouple app config from features --- pages/en/lb4/Application.md | 61 ++++++++++++++--------------- pages/en/lb4/Creating-components.md | 25 ++++++------ pages/en/lb4/Repositories.md | 4 +- pages/en/lb4/Using-components.md | 8 ---- 4 files changed, 47 insertions(+), 51 deletions(-) diff --git a/pages/en/lb4/Application.md b/pages/en/lb4/Application.md index 391e84e9e..5298d88c5 100644 --- a/pages/en/lb4/Application.md +++ b/pages/en/lb4/Application.md @@ -38,12 +38,11 @@ export class WidgetApplication extends Application { constructor() { // This is where you would pass configuration to the base constructor // (as well as handle your own!) - super({ - components: [RestComponent], - }); + super(); const app = this; // For clarity. // You can bind to the Application-level context here. // app.bind('foo').to(bar); + app.component(RestComponent); app.controller(SamoflangeController); app.controller(DoohickeyController); } @@ -77,8 +76,8 @@ a combination of both. ### Binding configuration Binding is the most commonly-demonstrated form of application configuration -throughout our examples, and in most cases, is the recommended method for -setting up your application. +throughout our examples, and is the recommended method for setting up your +application. In addition to the binding functions provided by [Context](Context.html), the `Application` class also provides some sugar functions for commonly used @@ -129,37 +128,34 @@ instance of the `WidgetRepository` class. The `Application` class constructor also accepts an [`ApplicationConfig`](http://apidocs.strongloop.com/@loopback%2fcore/#ApplicationConfig) -object which contains three collections: `components`, `controllers` and `servers`. -It will automatically create bindings for each of these collections as a part -of defining the application instance. +object which contains component-level configurations such as +[`RestServerConfig`](http://apidocs.strongloop.com/@loopback%2frest/#RestServerConfig). +It will automatically create bindings for these configurations and later be injected +through dependency injections. Visit [Dependency Injection](Dependency-injection.html) +for more details. {% include note.html content=" - More advanced binding configuration such as provider binding, or binding scopes + Binding configuration such as component binding, provider binding, or binding scopes are not possible with the constructor-based configuration approach. " %} ```ts -export class MyApplication extends Application { +export class MyApplication extends RestApplication { constructor() { super({ - components: [ - MagicSuite, - ], - servers: { - 'public': RestServer, - 'private': RestServer, - }, - controllers: [ - FooController, - BarController, - BazController, - ] - }); + rest: { + port: 4000, + host: 'my-host' + } + }) } } ``` #### Components +```ts +app.components([MyComponent, RestComponent]); +``` The components collection allows bulk binding of component constructors within your `Application` instance's context. @@ -167,21 +163,24 @@ For more information on how to make use of components, see [Using Components](Using-components.html). #### Controllers +```ts +app.controllers([FooController, BarController]); +``` Much like the components collection, the controllers collection allows bulk binding of [Controllers](Controllers.html) to the `Application` context. #### Servers -The servers collection is a Map of server constructors, whose keys are used -as part of the server's binding name. +```ts +app.servers([MyServer, GrpcServer]); +``` +The servers collection is also like the previous collections and allows +bulk binding of [Servers](Server.html). ```ts -const app = new Application({ - servers: { - 'public': RestServer, - 'private': RestServer, - }, -}); +const app = new Application(); +app.server(RestServer, 'public'); // {'public': RestServer} +app.server(RestServer, 'private'); // {'private': RestServer} ``` In the above example, the two server instances would be bound to the Application context under the keys `servers.public`, and `servers.private` respectively. diff --git a/pages/en/lb4/Creating-components.md b/pages/en/lb4/Creating-components.md index acf8c3f61..87da2cfb2 100644 --- a/pages/en/lb4/Creating-components.md +++ b/pages/en/lb4/Creating-components.md @@ -67,9 +67,8 @@ Applications can use `@inject` decorators to access the value of an exported Pro If you’re not familiar with decorators in TypeScript, see [Key Concepts: Decorators](Decorators.html) ```js -const app = new Application({ - components: [MyComponent] -}); +const app = new Application(); +app.component(MyComponent); class MyController { constructor(@inject('my-component.my-value') greeting) { @@ -273,15 +272,18 @@ export function RepositoryMixin>(superClass: T) { return class extends superClass { constructor(...args: any[]) { super(...args); - ... ... - // detect components attached to the app - if (this.options.components) { - for (const component of this.options.components) { - this.mountComponentRepository(component); - } - } } } + + /** + * Add a component to this application. Also mounts + * all the components' repositories. + */ + public component(component: Class) { + super.component(component); + this.mountComponentRepository(component); + } + mountComponentRepository(component: Class) { const componentKey = `components.${component.name}`; const compInstance = this.getSync(componentKey); @@ -306,7 +308,8 @@ import {Application} from '@loopback/core'; import {FooComponent} from 'components/src/Foo'; class AppWithRepoMixin extends RepositoryMixin(Application) {}; -let app = new AppWithRepoMixin({components: [FooComponent]}); +let app = new AppWithRepoMixin(); +app.component(FooComponent); // `app.find` returns all repositories in FooComponent app.find('repositories.*'); diff --git a/pages/en/lb4/Repositories.md b/pages/en/lb4/Repositories.md index 7cccdb918..68a497797 100644 --- a/pages/en/lb4/Repositories.md +++ b/pages/en/lb4/Repositories.md @@ -31,8 +31,10 @@ import { AccountRepository, CategoryRepository } from './repository'; // Using the Mixin class MyApplication extends RepositoryMixin(Application) {} + +const app = new MyApplication(); // AccountRepository will be bound to key `repositories.AccountRepository` -const app = new MyApplication({repositories: [AccountRepository]}); +app.repository(AccountRepository); // CategoryRepository will be bound to key `repositories.CategoryRepository` app.repository(CategoryRepository); ``` diff --git a/pages/en/lb4/Using-components.md b/pages/en/lb4/Using-components.md index e06573c2d..7abee0a8d 100644 --- a/pages/en/lb4/Using-components.md +++ b/pages/en/lb4/Using-components.md @@ -19,14 +19,6 @@ const app = new Application(); app.component(AuthenticationComponent); ``` -Alternatively, you can register a component through application config object. - -```js -const app = new Application({ - components: [AuthenticationComponent], -}); -``` - In general, components can contribute the following items: - [Controllers](Controllers.html)