Skip to content

Commit

Permalink
[WIP] Feature factoryFor
Browse files Browse the repository at this point in the history
  • Loading branch information
chadhietala committed Sep 26, 2016
1 parent 6ea3ed0 commit ef5301e
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 1 deletion.
23 changes: 22 additions & 1 deletion packages/container/lib/container.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { dictionary, symbol, setOwner, OWNER } from 'ember-utils';
import {
dictionary,
symbol,
setOwner,
OWNER,
assign
} from 'ember-utils';
import { ENV } from 'ember-environment';
import { assert, deprecate, runInDebug } from 'ember-metal';

Expand Down Expand Up @@ -130,6 +136,21 @@ Container.prototype = {
return factoryFor(this, this.registry.normalize(fullName), options);
},

factoryFor(fullName) {
assert('fullName must be a proper full name', this.registry.validateFullName(fullName));
let container = this;

return {
class: this.registry.resolve(fullName),
create(options = {}) {
let injections = injectionsFor(container, fullName);
let props = assign({}, injections, options);

return this.class.create(props);
}
};
},

/**
A depth first traversal, destroying the container, its descendant containers and all
their managed objects.
Expand Down
81 changes: 81 additions & 0 deletions packages/container/tests/container_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -712,3 +712,84 @@ QUnit.test('lookup passes options through to expandlocallookup', function(assert

assert.ok(PostControllerLookupResult instanceof PostController);
});


QUnit.test('#factoryFor must supply a fullname', (assert) => {
let registry = new Registry();
let container = registry.container();
assert.throws(() => {
container.factoryFor('chad-bar');
}, /Invalid Fullname, expected: 'type:name' got: chad-bar/);
});

QUnit.test('#factoryFor returns a factory creator', (assert) => {
let registry = new Registry();
let container = registry.container();

let Component = factory();
registry.register('component:foo-bar', Component);

let factoryCreator = container.factoryFor('component:foo-bar');
assert.ok(factoryCreator.create);
assert.ok(factoryCreator.class);
});

QUnit.test('#factoryFor class returns the factory function', (assert) => {
let registry = new Registry();
let container = registry.container();

let Component = factory();
registry.register('component:foo-bar', Component);

let factoryCreator = container.factoryFor('component:foo-bar');
assert.deepEqual(factoryCreator.class, Component);
});

QUnit.test('#factoryFor instance have a common parent', (assert) => {
let registry = new Registry();
let container = registry.container();

let Component = factory();
registry.register('component:foo-bar', Component);

let factoryCreator1 = container.factoryFor('component:foo-bar');
let factoryCreator2 = container.factoryFor('component:foo-bar');
let instance1 = factoryCreator1.create({ foo: 'foo' });
let instance2 = factoryCreator2.create({ bar: 'bar' });

assert.deepEqual(instance1.constructor, instance2.constructor);
});

QUnit.test('#factoryFor created instances come with instance injections', (assert) => {
let registry = new Registry();
let container = registry.container();

let Component = factory();
let Ajax = factory();
registry.register('component:foo-bar', Component);
registry.register('util:ajax', Ajax);
registry.injection('component:foo-bar', 'ajax', 'util:ajax');

let componentFactory = container.factoryFor('component:foo-bar');
let component = componentFactory.create();

assert.ok(component.ajax);
assert.ok(component.ajax instanceof Ajax);
});

QUnit.test('#factoryFor options passed to create clobber injections', (assert) => {
let registry = new Registry();
let container = registry.container();

let Component = factory();
let Ajax = factory();
registry.register('component:foo-bar', Component);
registry.register('util:ajax', Ajax);
registry.injection('component:foo-bar', 'ajax', 'util:ajax');

let componentFactory = container.factoryFor('component:foo-bar');

let instrance = componentFactory.create({ ajax: 'fetch' });

assert.equal(instrance.ajax, 'fetch');
});
4 changes: 4 additions & 0 deletions packages/ember-application/lib/system/application-instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ const ApplicationInstance = EngineInstance.extend({
return this;
},

factoryFor(fullName)/*: {class, create} */ {
return this.__container__.factoryFor(fullName);
},

setupRegistry(options) {
this.constructor.setupRegistry(this.__registry__, options);
},
Expand Down

0 comments on commit ef5301e

Please sign in to comment.