3
votes

I know Ember has a logger, but I wanted to create my own for learning purposes. I have a service called logger, and I want to be able to use this service everywhere. I have no problem injecting this service into components, controllers, and etc... I cannot figure out how to inject this service into a Utility I created without passing it through the create function. I don't want to have to pass my logger everywhere I create the utility. When I try to inject it into the object it complains about not being in a container. What's the best way to do this?

2
Do you talk about a function that you statically import? - Lux
Nope, I have a bunch of utilities that are each Ember.Objects. I want them to have access to the Logger service that I created. I cannot do Ember.inject.service() on a utility. - Taztingo
how do you create them? If you create them with a simple .create() they don't know about the application and so can not access a common logger server. However if you statically import the logger this will work. Or create your utilities with the DI container or inject the owner and use getOwner to lookup the service. - Lux
What's the DI container, and how do I inject the owner? - Taztingo

2 Answers

11
votes

Okay, its important to understand what Ember.inject.service actually does! Its like a shorter version for this:

myService: Ember.computed({
  get() {
    return Ember.getOwner(this).lookup('service:myService);
  }
}),

So what is this getOwner? It gives you the owner of an Object. Most of your objects like models, controllers, components, views and so on are created by the Dependency Injection (DI) container. For a class to be available on the DI container it needs to be registered.

Your default classes like controllers, routes, views are automatically registered by the Resolver. After registration you can inject them into other classes automatically when they are created by the container. Also into all instances created by the container the owner is injected.

Because the container itself is private, these public APIs are on the Application. getOwner also returns the application.

If you want to manually lookup an instance on the container you can use lookup.

For your utility class you probably use a normal .create() to get the object. This of course will not automatically couple it to your application, so the owner is not available. Also automatic injection will not work.

You can manually inject the owner with the ownerInjection:

myClass.create(Ember.getOwner(this).ownerInjection(), {...});

Then Ember.inject.service will work because getOwner will return the injected owner.

The other thing you could do is to register your utility objects on the container and then look them up. Then the owner is automatically injected.

-2
votes

I hit a similar problem a little while back.

The utilities are of type Ember.Object. So, all you have to do is inject the service into the Ember.Object class as a property.

Like this:

Ember.Object.reopen({
  testService:Ember.inject.service('testService')
});

Et Voila!Now you can literally use your service anywhere