Introduce namespaced component and service invocation#16158
Introduce namespaced component and service invocation#16158mixonic wants to merge 10 commits intoemberjs:masterfrom
Conversation
|
|
||
| function instantiateFactory(container, fullName, options) { | ||
| let factoryManager = EMBER_MODULE_UNIFICATION && options && options.source ? container.factoryFor(fullName, options) : container.factoryFor(fullName); | ||
| let factoryManager = EMBER_MODULE_UNIFICATION && options ? container.factoryFor(fullName, options) : container.factoryFor(fullName); |
There was a problem hiding this comment.
I think we can just pass container.factoryFor(fullName, options) all the time.
There was a problem hiding this comment.
Turns out some tests related to local lookup fail if we remove this.
| } | ||
| } | ||
|
|
||
| export function parseInjectionString(injectionString) { |
| } | ||
| } | ||
|
|
||
| export function lookupWithRawString(container, type, rawString) { |
| } | ||
| } | ||
|
|
||
| export function factoryForWithRawString(container, type, rawString) { |
packages/container/lib/index.js
Outdated
| FACTORY_FOR, | ||
| factoryForWithRawString, | ||
| lookupWithRawString, | ||
| RAW_STRING_OPTION_KEY as _RAW_STRING_OPTION_KEY |
There was a problem hiding this comment.
Confirm these don't become public API
packages/container/lib/registry.js
Outdated
| const VALID_FULL_NAME_REGEXP = /^[^:]+:[^:]+$/; | ||
| const missingResolverFunctionsDeprecation = 'Passing a `resolver` function into a Registry is deprecated. Please pass in a Resolver object with a `resolve` method.'; | ||
|
|
||
| let missingResolverFunctionsDeprecation = 'Passing a `resolver` function into a Registry is deprecated. Please pass in a Resolver object with a `resolve` method.'; |
There was a problem hiding this comment.
This line should remain whatever it was in master.
packages/container/lib/registry.js
Outdated
| if(EMBER_MODULE_UNIFICATION) { | ||
| /* With a rawString, the fullName doesn't need to contain a : */ | ||
| if (options && options[RAW_STRING_OPTION_KEY] && fullName) { | ||
| return true; |
There was a problem hiding this comment.
This needs review with @rwjblue @dgeb I'm not quite sure what to do here. The gist is that previously we required type:name but this check happens at low levels and now type alone is permitted (the name ends up in the rawString). Perhaps we should move this check out of the deep parts of the container instead of removing it in this PR.
There was a problem hiding this comment.
@mixonic I believe type alone is no longer permitted so we can remove this.
|
@mixonic FYI I tested this with the latest |
| specifier: type, | ||
| rawString: rawString | ||
| specifier, | ||
| targetNamespace |
There was a problem hiding this comment.
This could just be namespace, I don't think target is useful to discern it from anything else?
6a6c7b7 to
0aed89a
Compare
4dc4587 to
e6b3cbb
Compare
|
@mixonic and @dgeb We should clarify how we expect the "main" service of an addon to work. In my end-to-end test, If I have an addon called If I try to inject a service called |
e6b3cbb to
6f4ea49
Compare
This commit adds support for invoking a component or injecting a service
from a module unification namespace. It does so in a very targetted
manner, and specifically *avoids* adding support for namespaces to
lower-level APIs like lookup or factoryFor.
Ember itself doesn't perform any resolution steps for a lookup.
Instead, it defers resolution to a resolver class provided to the
application at runtime. For example this invocation:
```hbs
{{! app/templates/index.hbs }}
{{app-component}}
```
Causes a resolver invocation of:
``js
resolve(
'template:components/app-component', // a "fullName" formatted type:name.
'app/templates/index' // a referrer for this lookup
);
```
The resolver API has already been changed behind the module unification
feature flag to pass the second argument of "referrer" when appropriate.
A component from another namespace is invoked by putting the namespace
before a :: delemiter. For example an invocation:
```hbs
{{! src/ui/components/app-component/template.hbs }}
{{my-addon::addon-component}}
```
In order to resolve this namespace the resolver must be passed
`my-addon` is some form or another.
The current Ember container APIs are coupled heavily to the idea of a
"fullName". This is a string formatted as `type:name`, and expected to
resolve something. I'm hesitant to expand that syntax to something like
`type:optional-namespace::name`, especially since we would like to
replace the strings there with "specifiers" from the glimmer-di project
as we adopt more of that project.
Additionally we want existing
implementions of the resolver API to *not* be passed the namespace in the
first argument. If they were, they may resolve certain lookups in
ways that don't mesh our goals for the `::` syntax. For example a custom
resolver in someone's app may be splitting on `:` an expecting a syntax
in the string that matches `type:name`. It is ok to break those
resolvers for namespaced lookups, and we would rather they fail in some
way than resolve something that is wrong.
Instead, we've made an *additive* change to the resolver API. The
"rawString", the string invoking the lookup, is passed in the third
position:
```hbs
{{! src/ui/components/app-component/template.hbs }}
{{my-addon::addon-component}}
```
Resolves with:
```js
resolve(
'template:components/',
'src/ui/components/app-component/template',
'my-addon::addon-component'
);
resolve(
'component',
'src/ui/components/app-component/template',
'my-addon::addon-component'
);
```
Similarly service injections pass their "rawString":
```hbs
Ember.inject.service('my-addon::addon-service');
```
Resolves with:
```js
resolve(
'service',
undefined,
'my-addon::addon-service'
);
```
The resolver is expected to parse the invocation string.
- Still TODO cleanup rename rawString to targetNamespace
6f4ea49 to
5c460a9
Compare
|
Closing this in favor of #16319 |

This commit adds support for invoking a component or injecting a service from a module unification namespace. It does so in a very targeted manner, and specifically avoids adding support for namespaces to lower-level APIs like lookup or factoryFor.
Ember itself doesn't perform any resolution steps for a lookup. Instead, it defers resolution to a resolver class provided to the application at runtime. For example this invocation:
Causes a resolver invocation of:
The resolver API has already been changed behind the module unification feature flag to pass the second argument of "referrer" when appropriate.
A component from another namespace is invoked by putting the namespace before a
::delemiter. For example an invocation:In order to resolve this namespace the resolver must be passed
my-addonis some form or another.The current Ember container APIs are coupled heavily to the idea of a "fullName". This is a string formatted as
type:name, and expected to resolve something. I'm hesitant to expand that syntax to something liketype:optional-namespace::name, especially since we would like to replace the strings there with "specifiers" from the glimmer-di project as we adopt more of that project.Additionally we want existing implementions of the resolver API to not be passed the namespace in the first argument. If they were, they may resolve certain lookups in ways that don't mesh our goals for the
::syntax. For example a custom resolver in someone's app may be splitting on:an expecting a syntax in the string that matchestype:name. It is ok to break those resolvers for namespaced lookups, and we would rather they fail in some way than resolve something that is wrong.Instead, we've made an additive change to the resolver API. The "rawString", the string invoking the lookup, is passed in the third position:
Resolves with:
Similarly service injections pass their "rawString":
Ember.inject.service('my-addon::addon-service');Resolves with:
The resolver is expected to parse the invocation string.
TODO:
mainlookups of services.store: Ember.inject.service('ember-data')and the addonssrc/services/main.jswould be resolved.moduleNameis on a template and what it should be.