I don't like doing injections in the initializers, what's wrong with me?


#1

Hi,

It’s pretty frequent to see in addons an initializer that does a bunch of injections such as: application.inject('route', serviceName, serviceLookupName);.

I understand it’s easy and works well, but it seems to me that it makes the application less readable. I’d like to read from you about whether this is a good practice and what could be the reasons to prefer automatic injection over a manual injection at class-level.

From my perspective, there are a number of downsides:

  • This is too broad: If I want to inject something in all the objects of type X, why wouldn’t I extend the initial type and use that instead?
  • looking at a class (let’s say a Component), I have to know and remember beforehand that it is not “only” an Ember Component but a “component with X and Y already injected”. I don’t like implicit behaviour :stuck_out_tongue:
  • I can’t easily say where the injection is used. When you manually do the injection on specific classes, it makes it much easier to understand the impact of your injection in your app.

Do you agree or disagree? Do you inject dependencies in your classes from the initialisers? Is there a recommended practice at all?

Bye, thanks for reading


#2

Another downside is that it makes the item in question not easy to unit / integration test. This is because those initializers are only ran for acceptance tests (which boot a full application).


#3

I agree. I like to inject services like this: https://github.com/broerse/ember-cli-blog/blob/master/app/adapters/application.js#L9 over injecting in initializers. Don’t know if this is a recommended practice.


#4

I personally prefer “manual” Ember.inject.service style injections whenever possible.


#5

That’s the interesting part: what are the usecases where it is necessary to inject globally?


#6

There are only Ember.inject API’s for specific types: service and controller. When dealing with other types, you don’t have that as an option. However, you could still make a computed property that does getOwner(this).lookup instead.