简体   繁体   中英

Ember Inject Service into Ember Utility

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?

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.

Not sure which Ember version initiated this pattern but the Ember documentation contains the answer to that question starting from v4.3:

import { inject as service } from '@ember/service';
import { getOwner, setOwner } from '@ember/application';

class Item {
  @service('shopping-cart') cart;

  constructor(context) {
    setOwner(this, getOwner(context));
  }

  function addToCart() {
    this.cart.add(this);
  }
}

// On any framework object...
let item = new Item(this);
item.addToCart();

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM