-
-
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
Container / Registry Reform #11440
Container / Registry Reform #11440
Conversation
This looks great. 👍 |
@stefanpenner ping re: details on your proposal to replace |
@stefanpenner ping ping (the dreaded double ping, best employed on Monday mornings). |
ref(registry, App); | ||
|
||
// TODO2.0 remove deprecated case in which initialize takes two args | ||
if (ref.length === 2) { |
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.
If this is not going to land in a 1.13.x release, this can be removed I think.
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.
Yes, that is the question. I'd hate to land this post-2.0 and carry forward all these deprecations until 3.0.
The lack of movement on this issue concerns me. If we do nothing, the following will need to be carried forward into all Ember 2.x releases:
I'm trying to get attention to this issue now because deprecating the above is messy, and those messy deprecations will need to be carried forward through all 2.x releases. I'd like to avoid a second long-lasting wave of container / registry deprecation warnings like the one experienced after the SSR refactor. On the other hand, if we establish clear public interfaces for 2.0, we can demystify Ember's DI approach through docs and guides. Even if this approach is tweaked during 2.x (e.g. access to I know time is short now, but please consider this low hanging fruit. Just say the word and I'll rebase ASAP. Note: this PR also contains a fix to #11174 which should probably be merged regardless of the bigger picture changes. |
I would like to give this some time. But my plate of awfully full. I'll try to find time yet this week. But my queue is quite saturated |
@stefanpenner If we cannot get your feedback on this, can we get this merged in? We are quickly running out of time, @dgeb has put a ton of effort getting it backwards compatible, and both me and @wycats are 👍 on it. |
Sure, but I reserve the right to complain violently down the road |
Have no fear, I even complain violently about the PR's that I made. |
ee45f96
to
81654c0
Compare
I made significant progress with a rebase last night, but still have a couple failing builds: https://travis-ci.org/emberjs/ember.js/builds/71200614 Will do another pass of rebasing/fixing today ... |
The old-jquery build was a spurious failure, I restarted and it is passing now. The node-tests build is a legit failure, you need to update https://github.com/emberjs/ember.js/blob/master/tests/node/app-boot-test.js#L97 to use |
49c95fd
to
ba47f70
Compare
@dgeb and I just discussed at length the path forward for this feature. The following is the rough result: This PR does quite a few things, but the vast majority of the changes are additive and not breaking. This means we can add those features in the 2.x cycle at any time, behind a feature flag. The primary areas that we identified that were potentially breaking were:
Object.defineProperty(ApplicationInstance, 'container', {
configurable: true,
enumerable: false,
get() {
var instance = this;
return {
lookup() {
Ember.deprecate('Using `ApplicationInstance.container.lookup` is deprecated. Please use `ApplicationIntance.lookup` instead.');
instance.lookup(...arguments);
}
}
}); Both of those scenarios can be completely mitigated when the new feature is enabled. Remaining action items (also added to description above):
|
a56866c
to
e180c04
Compare
Mix in to both `Application` and `ApplicationInstance` classes to provide consistent public access to their internally maintained registries.
Pass the related Application, which the instance can inspect to obtain the initialization data that it needs. This eliminates the need to set `applicationRegistry` on the instance, which was always an anti-pattern.
The `RegistryProxy` mixin now maintains the registry instance as `__registry__`. As appropriate, the equivalent `RegistryProxy` methods are called instead of directly accessing the `registry`.
Registry access must go through the Application now.
Now that container will be fully privatized, we can relax naming of members like `registry` that won't be accessed outside of the framework.
Mix in to `ApplicationInstance` class to provide public access to a few select methods on the encapsulated container.
Instead, allow the application's resolver to be invoked only as part of the fallback strategy for the application instance's registry. This has a couple benefits: * It allows registrations made in the app instance's registry to be resolved before falling back to the app's registry, rather than hitting the resolver beforehand. This is important for scenarios such as testing in which custom registrations need to take precedence over the resolver. * It is also more efficient in the case when the app's registry's registrations are used to resolve, because it avoids calling the same resolver twice before finally getting the registration. [Closes emberjs#11174]
* Ensure that `Container#_registry` remains supported for now. Can be deleted once cont/reg reform is enabled by default. * Continue to expose `registry` and `container` on `ApplicationInstance`. These can be removed once cont/reg reform is enabled, but we’ll still need to expose `ApplicationInstance.container.lookup` until 3.0. * Flag deprecation of Application initializer `initialize` arguments.
@rwjblue I've completed the tasks. This has been rebased, feature-flagged, and is ready for review. |
Thanks @dgeb! |
@dgeb if this is supposed to privatize things, did you miss this one? https://github.com/dgeb/ember.js/blob/c353c383b666474e5fb2c2d6fa17934946dcc9ca/packages/container/lib/container.js#L240 should that not be |
@krisselden - This was affecting a public API to be used by initializers and instanceInitializers, but does not change access from within an object looked up from the container. Changing I'm totally in favor of exposing some sort of limited public API for use here, but we must tread carefully and ensure no breakage... |
@krisselden I personally am in favor of deprecating Of course, I also agree with @rwjblue that we must tread carefully and ensure no breakage. |
This is an implementation of RFC 46. The goal is to fully encapsulate and privatize the
Container
andRegistry
classes by exposing a select subset of public methods onApplication
andApplicationInstance
.This is achieved by introducing two new proxy mixins:
RegistryProxy
andContainerProxy
.Application
now mixes inRegistryProxy
.ApplicationInstance
mixes in bothRegistryProxy
andContainerProxy
.RegistryProxy
RegistryProxy
maintains the registry as a private__registry__
property.The following registry methods are exposed publicly via
RegistryProxy
:resolveRegistration
- alias forresolve
register
unregister
hasRegistration
- alias forhas
registerOption
- alias foroption
registerOptions
- alias foroptions
registeredOptions
- alias forgetOptions
registerOptionsForType
- alias foroptionsForType
registeredOptionsForType
- alias forgetOptionsForType
inject
- alias forinjection
ContainerProxy
ContainerProxy
maintains the container as a private__container__
property.The following container methods are exposed publicly via
ContainerProxy
:lookup
lookupFactory
Privatization of Container and Registry
The introduction of these interfaces allows for the complete privatization of the
Container
andRegistry
classes. This allows for their architecture and documentation to be cleaned up. For instance, aContainer
can freely reference its associatedRegistry
asregistry
rather than_registry
, as it can be assumed that only framework developers will reference this property.Simplification of Initializers
Application
initializers now receive a single argument toinitialize
:application
. Receiving two arguments is still allowed, but deprecated.Likewise,
ApplicationInstance
initializers still receive a single argument toinitialize
:applicationInstance
.Allow Application Instance's Registrations to take Precedence over the Resolver
This work also addresses #11174 by only associating a resolver with the
Application
's registry and not withApplicationInstance
's registry.This has a couple benefits:
Remaining Action Items:
appInstance.container.lookup
continues to work.