-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
[FEATURE ember-container-inject-owner]: Inject owner
instead of container
during lookup
.
#11874
Conversation
let container = get(this, '__container__'); | ||
let result = container.lookup(...arguments); | ||
if (result && result.owner === undefined) { | ||
result.owner = this; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we may want to be careful about owner, we dont want to smash users properties on collision.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, definitely open to alternatives to owner
- it's short and sweet, but that also means it might be commonly used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at the very least some underscores, at the very best non-enumerable.
But why can't we just use container ? it seems like its the same thing...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. For better or worse we have already reserved this.container
, and any top level "word" we take will potentially collide with something.
I'm not opposed to something better, but keeping it as container
would preserve current this.container.lookup
semantics and not take over another reserved word...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume from the syntax highlighting that you mean __container__
, right?
My concern with using anything related to "container" publicly is that it breaks the clean encapsulation. Devs will continue to think of Container
as semi-private and try to dig into container.registry
for instance.
Maybe __owner__
? It's probably safe from collisions, clearly private, and clearly not an instance of a Container
. I guess I've been unclear how private / public we want this to appear (given that container
has been available without dunderscores).
EDIT: typed as a reply to @stefanpenner above before seeing @rwjblue's comment.
The issue of As I replied, I didn't include this in #11440 because it wasn't part of my original RFC and so I thought it appropriate to discuss it separately. If feedback is positive, I'll bring the tests / implementation inline. |
injections.container = container; | ||
|
||
if (isEnabled('ember-registry-container-reform')) { | ||
Object.defineProperty(injections, 'container', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this ran once for each object looked up? Does that pose a performance issue? I am unsure, I'd love others' thoughts...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it (if the code hasn't changed since i wrote it) should only run 1 per factory. If we are not doing that anymore, we should likely chat, because it would be a big perf hit to run every injection rule for every instance.
@dgeb owner still is too much of a reserved word, why not |
We can have a public API via an accessor that knows the symbol, import getOwner from 'ember-injections' getOwner(this).lookup() and we can have Ember.injectService etc. understand this for lazy injections. |
My issue with using
Seems good to me. |
e586dab
to
b715907
Compare
Where are we at with this? |
Sorry to let this sit. Would |
@dgeb - Yeah, seems like a good path forward for now (we can always do more bikeshedding ). I think this will need to use a different feature flag name though, as we are going to ship the container / registry reform feature before this is ready. |
@dgeb - I believe we are generally in agreement with your last comment. General checklist added to PR description. |
@rwjblue - thanks - I'll try to get to this soon! |
63be392
to
8e6c1fe
Compare
I've completed all the tasks in the checklist except for the following:
If we use |
891779f
to
9b0b7fe
Compare
Ok, I'm now injecting the container via The checklist is now complete, but CI is apparently not happy yet. |
162830a
to
c04429e
Compare
Finally green and ready for review :) |
@rwjblue - let me know when you're ready to review this and I'll be glad to rebase it. |
Thank you. Sorry for the delay, I've gotten a bit behind on my triaging and PR review while in London for EmberCamp London. |
} | ||
} | ||
|
||
// TODO - remove when Ember reaches v3.0.0 | ||
function injectDeprecatedContainer(object, container) { | ||
Object.defineProperty(object, 'container', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could likely install the container in injections via a symbol, then leave this defProp on CoreObject, that way all ember objects injections don't need to do the redefine. (only those that are not decedents of CoreObject would?
the I suspect, something like: View.extend(ownerInject(), {
}).create() would do the trick |
I'm open to using a helper to clean up the tests. Keep in mind we need to pass For example:
Alternative names: Another possible helper:
Alternative name: @stefanpenner @rwjblue any preference? |
After chatting with @rwjblue, we're looking to export the This will allow us to set the owner without a helper in Ember's tests:
@stefanpenner let us know if you have any objections. |
nope this sounds good. |
Once this lands, we will seal a private but often used feature. One for example used heavily by ember-data. Do we have strategies in-place to provide public alternatives? |
Yes, this PR exposes the new public API. Instead of using this (which is private):
Once this feature is enabled, you would do:
The only things exposed on the returned owner are the functions that we have already decided are public (during he ember-container-reform feature that landed in 2.1). |
Also, please note: this.container still fully works with a deprecation (since it is SUPER heavily used). |
…helpers. Use a symbol to obscure the owner property.
…tainer` during `lookup`. This change represents the final brick needed to wall off the `Container` as fully private. The Container no longer injects itself into every object that it looks up. Instead, it uses the new `setOwner` helper to inject the "owner", which can then be retrieved from any object using the new `getOwner` helper. The current net effect is that an app instance is injected into every looked up object instead of that app instance's container. This provides clean, public access to methods exposed by the app instance's ContainerProxy and RegistryProxy methods. It also guarantees that the only supported path to get to a Container or Registry is through a proxied method. This guarantee is important because it allows for owner-specific logic to be placed in proxy methods. In the future, other classes, such as Engine (coming soon), may mix in ContainerProxy and thus have the potential to be "owners". This work is behind the `ember-container-inject-owner` flag. Without this flag enabled, the Container will continue to inject itself directly into objects that it instantiates (as `container`).
98bd567
to
9845a9a
Compare
Ok - I've applied the changes discussed above and all is green (except for the sauce build). Let me know if there's anything else I can do to help this land. |
owner
instead of container
during lookup
.owner
instead of container
during lookup
.
[FEATURE ember-registry-container-reform] WIP: Inject `owner` instead of `container` during `lookup`.
#12555 is a checklist of items needed to be done for enabling the new feature. |
@dgeb sounds good |
Awesome! |
This change represents the final brick needed to wall off the
Container
as fully private.The Container no longer injects itself into every object that it looks
up. Instead, the owner of the Container is injected as
owner
by theContainerProxy mixin.
The current net effect is that an app instance is injected into every
looked up object instead of that app instance's container. This
provides clean, public access to methods exposed by the app
instance's ContainerProxy and RegistryProxy methods. It also guarantees
that the only supported path to get to a Container or Registry is
through a proxied method. This guarantee is important because it allows
for owner-specific logic to be placed in proxy methods.
In the future, other classes, such as Engine (coming soon), may mix in
ContainerProxy and thus have the potential to be "owners".
Note 1: This work is behind the ember-registry-container-reform flag.
Note 2: Totally open to alternatives to the name
owner
. I was drawnto this name because the owner of the container "owns" the instantiated
objects to the extent that its responsible for their cleanup.
Note 3: This is still a WIP and will require changes throughout the
test suite for compatibility.
owner
to__owner__
(actually, use symbol instead).getOwner
/setOwner
functions.container
in an object looked up from the container.Object.defineProperty
supporting deprecated access tothis.container
is called a single time per factory (and not once for every created instance).ember-container-registry-reform
is already enabled). Perhapsember-container-inject-owner
?