From 6d063b8f7111190e3535b4503b78fbcc10241439 Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Thu, 19 Nov 2015 19:00:53 -0500 Subject: [PATCH] [BUGFIX beta] Expose ownerInjection method on ContainerProxy. The `ember-container-inject-owner` feature provides a public API for accessing various container/registry functions. Unfortunately, creating an instance that has access to the same owner is a somewhat annoying API compared to what we would do today. In Ember 2.2 you would often do this (though it still uses private API): ```js User.create({ container: this.container, username: 'John' }); ``` But in 2.3.0-beta.1 to do roughly the same thing, you would have to do: ```js var options = { username: 'John' }; setOwner(options, getOwner(this)); User.create(options); ``` This is definitely less ergonomic for a perfectly supported case. With the changes added here, you would use the following: ```js User.create( getOwner(this).ownerInjection(), { username: 'John' } ); ``` --- packages/container/lib/container.js | 14 ++++++++++- packages/container/tests/container_test.js | 12 +++++++++- .../lib/mixins/container_proxy.js | 21 ++++++++++++++++ .../tests/mixins/container_proxy_test.js | 24 +++++++++++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 packages/ember-runtime/tests/mixins/container_proxy_test.js diff --git a/packages/container/lib/container.js b/packages/container/lib/container.js index 34693880007..39943bf8493 100644 --- a/packages/container/lib/container.js +++ b/packages/container/lib/container.js @@ -2,7 +2,7 @@ import Ember from 'ember-metal/core'; import { assert, deprecate } from 'ember-metal/debug'; import dictionary from 'ember-metal/dictionary'; import isEnabled from 'ember-metal/features'; -import { setOwner } from './owner'; +import { setOwner, OWNER } from './owner'; import { buildFakeContainerWithDeprecations } from 'ember-runtime/mixins/container_proxy'; /** @@ -159,6 +159,18 @@ Container.prototype = { } else { resetCache(this); } + }, + + /** + Returns an object that can be used to provide an owner to a + manually created instance. + + @private + @method ownerInjection + @returns { Object } + */ + ownerInjection() { + return { [OWNER]: this.owner }; } }; diff --git a/packages/container/tests/container_test.js b/packages/container/tests/container_test.js index dafec3f7855..d750ce806b1 100644 --- a/packages/container/tests/container_test.js +++ b/packages/container/tests/container_test.js @@ -1,7 +1,7 @@ import Ember from 'ember-metal/core'; import Registry from 'container/registry'; import factory from 'container/tests/test-helpers/factory'; -import { getOwner } from 'container/owner'; +import { getOwner, OWNER } from 'container/owner'; import isEnabled from 'ember-metal/features'; var originalModelInjections; @@ -519,6 +519,16 @@ QUnit.test('Lazy injection validations are cached', function() { container.lookup('apple:main'); }); +QUnit.test('An object with its owner pre-set should be returned from ownerInjection', function() { + let owner = { }; + var registry = new Registry(); + var container = registry.container({ owner }); + + let result = container.ownerInjection(); + + equal(result[OWNER], owner, 'owner is properly included'); +}); + if (isEnabled('ember-container-inject-owner')) { QUnit.test('A deprecated `container` property is appended to every object instantiated from an extendable factory', function() { let registry = new Registry(); diff --git a/packages/ember-runtime/lib/mixins/container_proxy.js b/packages/ember-runtime/lib/mixins/container_proxy.js index e9c67e0be07..ce375799cc3 100644 --- a/packages/ember-runtime/lib/mixins/container_proxy.js +++ b/packages/ember-runtime/lib/mixins/container_proxy.js @@ -23,6 +23,27 @@ export default Mixin.create({ */ __container__: null, + /** + Returns an object that can be used to provide an owner to a + manually created instance. + + Example: + + ``` + let owner = Ember.getOwner(this); + + User.create( + owner.ownerInjection(), + { username: 'rwjblue' } + ) + ``` + + @public + @method ownerInjection + @return {Object} + */ + ownerInjection: containerAlias('ownerInjection'), + /** Given a fullName return a corresponding instance. diff --git a/packages/ember-runtime/tests/mixins/container_proxy_test.js b/packages/ember-runtime/tests/mixins/container_proxy_test.js new file mode 100644 index 00000000000..5aab24999d2 --- /dev/null +++ b/packages/ember-runtime/tests/mixins/container_proxy_test.js @@ -0,0 +1,24 @@ +import { OWNER } from 'container/owner'; +import Registry from 'container/registry'; +import Container from 'container/container'; +import ContainerProxy from 'ember-runtime/mixins/container_proxy'; +import EmberObject from 'ember-runtime/system/object'; + +QUnit.module('ember-runtime/mixins/container_proxy', { + setup() { + this.Owner = EmberObject.extend(ContainerProxy); + this.instance = this.Owner.create(); + + let registry = new Registry(); + + this.instance.__container__ = new Container(registry, { + owner: this.instance + }); + } +}); + +QUnit.test('provides ownerInjection helper method', function(assert) { + let result = this.instance.ownerInjection(); + + assert.equal(result[OWNER], this.instance, 'returns an object with the OWNER symbol'); +});