Is it possible to work with Dependency Injection in your own Util classes/objects which are extending Ember.Object
or with Mixin
s so that for example you can use a shared value (as a user object) throughout the whole application via Dependency Injection instead of referencing it from the App.
namespace? Also, is this somehow possible in Ember App Kit
?
You need to use an application initializer. It’s fired when your application becomes ready, and it’s passed the application container. From there, you can register and inject objects.
Taken (roughly) from the Ember-Data code:
Em.onLoad('Ember.Application', function(Application) {
Application.initializer({
name: 'userWidgetInitializer',
initialize: function(container, application) {
// Register the object you want to inject. Let's say you want to inject the UserWidget class.
application.register('widget:userWidget', App.UserWidget, { singleton: true });
// Inject the user widget into every controller instance
// Because we labeled it a singleton, all controllers will get the same instance
// The widget can be accessed with the controller's `widget` property
application.inject('controller', 'widget', 'widget:userWidget');
}
});
});
Also, note that you can only register Ember.js factories (classes) with the container. If you wanted to register a non-Ember object, see this question.
Thanks @gordon_kristan - that’s also what I found out (actually I’m registering and injecting util classes in Controller
s and Route
s like this)
What I really wanted to know is, how I could inject these dependencies into other Util
classes which are not part of the Ember Framework (like Controller
or Route
) and how I could probably access the container
from these classes to make use of it (by calling container.lookup('session_util:app')
or something like this).
Actually I created a ApplicationContainer
class which is nothing but a new Ember.Container()
and import
it in every Util
class I need it… but this seems like bad practice to me
I think registering your utility classes with the container will automatically inject a container instance into them. So if you register your Widget
class with the container, all Widget
instances will now contain a container
property that you can use.
As far as I can tell, dependency injection doesn’t apply when you manually create utility classes. It only happens when using Container.lookup
or when using the factory provided by Container.lookupFactory
. The registered objects don’t seem to have access to container
either way.
App = Ember.Application.create();
App.IndexRoute = Ember.Route.extend({
setupController: function(controller) {
// Created like a basic Ember.Object.
var obj1 = App.MyObject.create();
console.log('obj1.service', obj1.service);
// Created by looking up the object in Container.
var obj2 = this.container.lookup('object:main');
console.log('obj2.service', obj2.service);
// Created using the factory from Container.
var objectFactory = this.container.lookupFactory('object:main');
var obj3 = objectFactory.create();
console.log('obj3.service', obj3.service);
}
});
Ember.Application.initializer({
name: 'injectMyObject',
initialize: function(container, application) {
application.register('object:main', App.MyObject, {singleton: false});
application.register('service:main', App.MyService);
application.inject('object', 'service', 'service:main');
}
});
App.MyService = Ember.Object.extend();
App.MyObject = Ember.Object.extend();
See this JSFiddle: Ember object lookup versus create - JSFiddle - Code Playground