Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] feat(context): Allow components to expose a list of bindings #929

Closed
wants to merge 3 commits into from

Conversation

raymondfeng
Copy link
Contributor

@raymondfeng raymondfeng commented Jan 30, 2018

The PR adds a few APIs:

  • Context.bind(Binding) - bind an binding to the current context.
  • Component.classes and Component.bindings - allow a component to declare an array of bindings or a map of classes.

Checklist

  • npm test passes on your machine
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • Related API Documentation was updated
  • Affected artifact templates in packages/cli were updated
  • Affected example projects in packages/example-* were updated

@raymondfeng raymondfeng changed the title Component bindings feat(context): Component bindings Jan 30, 2018
@bajtos
Copy link
Member

bajtos commented Jan 30, 2018

@raymondfeng what is the expected behavior when app.bind receives a binding that's already bound to another context?

const ctx1 = new Context();
const ctx2 = new Context();

const b = ctx1.bind('foo').to('bar');
ctx2.bind(b2);

Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@raymondfeng I am concerned about the downsides of allowing users to add Binding instances directly to the context.

What high-level problem (end-to-end scenario) are you trying to address by this patch?

What other solutions have you considered and rejected?

*/
bind(key: string): Binding {
bind(keyOrBinding: string | Binding): Binding {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not very happy about this method overload. So far, bind is always followed with .to{something}() and possibly other modifiers like inScope, etc. Do you expect people will call those modifiers when binding a Binding directly? I don't.

Instead of overloading the existing bind method, I am proposing to add a new method called add. That way we have to distinctive usage patterns:

ctx.bind('foo').to('bar').inScope(BindingScope.SINGLETON);

const b = new Binding('foo').to('bar').inScope(BindingScope.SINGLETON);
ctx.add(b);

@@ -17,6 +17,13 @@ describe('Context', () => {
expect(result).to.be.true();
});

it('accepts a binding', () => {
const binding = new Binding('foo').to('bar');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code looks rather silly to me, as it reads new binding 'foo' to 'bar'.

IMO, the API of Binding class was not designed to support usage outside of Context and we need to fix this problem before allowing components to contribute new bindings via Binding instance.

@raymondfeng raymondfeng force-pushed the component-bindings branch 2 times, most recently from 0e8b945 to 543c305 Compare January 30, 2018 17:18
@raymondfeng
Copy link
Contributor Author

@bajtos The main use case is to contribute bindings from a component (without accessing the context). The bindings need to be set up (such as scope or value) before they are bound to the app later. See https://github.com/strongloop/loopback-next/blob/543c30509f3a28d523c7724c2fd422fee99dc40d/packages/core/src/component.ts#L82.

Alternative solutions are:

  • Declare a dependency injection for the component class and use the injected ctx to bind by code.

See https://github.com/strongloop/loopback-next/blob/543c30509f3a28d523c7724c2fd422fee99dc40d/packages/core/test/unit/application.test.ts#L42

@raymondfeng
Copy link
Contributor Author

what is the expected behavior when app.bind receives a binding that's already bound to another context?

We're addressing it with 62fda01.

@raymondfeng raymondfeng changed the title feat(context): Component bindings [WIP] feat(context): Component bindings Feb 1, 2018
@raymondfeng raymondfeng changed the title [WIP] feat(context): Component bindings [WIP] feat(context): Allow components to expose a list of bindings Feb 1, 2018
@bajtos
Copy link
Member

bajtos commented Feb 2, 2018

Allow components to expose a list of bindings

I agree this is an important and valid requirement that we need to address, and I also agree that the current status (only Providers can be provided by components for DI registration) is too limited.

At the same time, these improvements is out of scope of our MVP release, therefore we should postpone them until the MVP is done.

You pull request is a reasonable incremental improvement. However, I am concerned that the current design of extensions is sort of a dead end and the changes proposed here are only digging a deeper hole we will have to get out of. Let's talk about that in #953, so that the discussion in this pull request can stay focused on your proposed code changes.

@bajtos bajtos added post-GA and removed LB4 GA labels Jun 28, 2018
@dhmlau dhmlau removed the non-DP3 label Aug 23, 2018
@bajtos
Copy link
Member

bajtos commented Oct 26, 2018

There have been no updates in this pull request for many months, I am closing it for now. @raymondfeng feel free to reopen if you get time to continue this work. (Considering how outdated these changes are, it may be better to start from scratch.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants