Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change wording for injecting a service #273

Closed
edouard-lopez opened this issue Nov 23, 2017 · 18 comments
Closed

Change wording for injecting a service #273

edouard-lopez opened this issue Nov 23, 2017 · 18 comments

Comments

@edouard-lopez
Copy link

edouard-lopez commented Nov 23, 2017

When writing route, component, etc. in Ember we often use the Dependency Injection pattern.

Below I'm showing current situation and proposing, what I believe to be, a simpler/more explicit wording than current one.

Current status (Aliasing Method)

Use an alias to explicit what it is.

import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default Route.extend({
  authManager: service('auth'),
  i18n: service(),
  …
});

Proposal (Direct Name)

Use the original method's name as it explicits what it does.

import Route from '@ember/routing/route';
import { inject } from '@ember/service';

export default Route.extend({
  authManager: inject('auth'),
  i18n: inject(),
  …
});

Accessing

Stays the same:

this.get('i18n').t(`my.text-to-translate`)

What next?

  • Share your experience, feedbacks and arguments pros/cons.
  • Update documentation to reflect decision.
@mikkopaderes
Copy link

There's nothing stopping you from using inject instead of service. I believe service is just explicit in the guides because you can also inject controllers.

@edouard-lopez
Copy link
Author

@rmmmp I update What next? section to reflect documentation should be updated too.

@locks
Copy link
Contributor

locks commented Nov 23, 2017

We alias the name to distinguish from import { inject } from '@ember/controller';.
I also prefer to read service() as then I know what's being injected, instead of the more generic inject.

@edouard-lopez
Copy link
Author

Thanks @locks,
I agree with you that in case one need to distinguish service/controller injection then one should alias, but why make it the default recommendations?

It sounds like a silver bullet approach to me for 2 reasons:

  • I have met the need to distinguish only seldom ;
  • controller are supposed to go away in future version of ember.

@buschtoens
Copy link
Contributor

As a counter-argument to your second point: theoretically you could ad-hoc inject anything you like. Addons could chose to export an inject method / decorator.

@edouard-lopez edouard-lopez changed the title Change wording for Injecting a service Change wording for injecting a service Nov 23, 2017
@pusle
Copy link

pusle commented Apr 8, 2018

After upgrading from Ember Cli 2.12 to 3.0 I get a lot of errors telling me to

4:12 error Use import { inject } from '@ember/service'; instead of using Ember.inject.service ember/new-module-imports

when running ember serve after the upgrade. I have gone trough a lot of these files and updated as told. Should the error notifications say to use import { inject as service } from '@ember/service'; instead?

@Serabe
Copy link
Member

Serabe commented Apr 8, 2018

@pusle I opened an issue to check that problem ember-cli/eslint-plugin-ember#250

@pusle
Copy link

pusle commented Apr 8, 2018

@Serabe Thank you.

@rwjblue
Copy link
Member

rwjblue commented Apr 9, 2018

FWIW, I personally prefer import { inject as injectService } from '@ember/service' but inject as service is still better than just inject.

@mehulkar
Copy link
Contributor

I've always thought it was strange that the injection function came from a package of the thing that was being injected. Ideally, I'd want import { service, controller } from '@ember/injections', but not sure if a new package really makes sense just for a couple of functions.

That said, I wonder if anyone every injects something that isn't a service. I know it's possible to inject controllers, but I've personally never done it, and it seems like an anti pattern?

@sarbbottam
Copy link

👍 for import { inject as injectService } from '@ember/service'.


May be @ember/service coud rename inject to injectService; then we could import it explicitly an less ambigously - import { injectService } from '@ember/service'.

@RuslanZavacky
Copy link

My couple cents - it very much depends on the contexts and approach for DI, but DI shouldn't be aware of what you inject. If it is service, or repository or controller. Less concepts to think about, for the same goal does look better. In the end, everything is a "service". Controllers can be services as well, as they contain logic.

const great = inject('great-controller');
const amazing = inject('amazing-service');

In the end, you will use great.method() and amazing.nextMethod(). Was it important, that one was controller and another was service?

For small context from another framework, from another language. They've started as separation and controllers weren't even injectable. But the way how you can inject something else was always the same. After some time (read 10+ years) more and more patterns were emerging that Controllers can be services too, as they can share what they do and still be "controller" for semantic. So now, you can inject Controller the same way as everything else - services, repositories, controllers, helpers, etc.

@locks
Copy link
Contributor

locks commented Jan 18, 2019

Was it important, that one was controller and another was service?

I do think that there is an important distinction here, which is the reason for there being two inject, one from @ember/controller and one from @ember/service.

In the end, everything is a "service". Controllers can be services as well, as they contain logic.

You are using two different meanings of the word "service", the general concept of a service, and the particular implementation of Service in Ember.
Yes, a Controller is a singleton but it has a specific lifecycle that is maintained by the Route*, unlike a Service. This changes how you interact with it because you are dependent of whether the Route the Controller belongs to has been visited.

  • I am ignoring non-routable controllers as they are not used in modern Ember.

@RuslanZavacky
Copy link

As a consumer of API, I do know what I want to inject.

Question is - do I need to know, that under the hood, ember is doing something different with this injections? I would vote for no. How I see the goal of DI - I need to be able to get what I've asked for and use it without knowing or relying on special implementation that is doing that.

I understand, that there might be some overhead, to understand what was "asked for", eg. was it service or controller, but such overhead should be minimal.

I am also probably mixing this RFC for doc changes and some improvements under the hood.

@EndangeredMassa
Copy link

I also care about this from the perspective of a consumer dev, just trying to write their component that needs a service. Whenever I need to do this, I have to remember that it's technically inject I'm looking for, which makes me question what package it comes from.

I would prefer:

import { service } from '@ember/service';

Which is certainly confusing from the package's own perspective--to expose a service function from the service module. But as a convenience for consumers, I think it's worth it. It could strictly be an alias, too. I don't think we need to remove inject from the export list.

@pzuraq
Copy link
Contributor

pzuraq commented Apr 17, 2019

This is also something that interferes with tooling. With proper types and a modern editor, if the export were named service you would be able to just start typing it out, and the editor would autocomplete it and then add the import to the top of the file for you. This is a huge ergonomics win IMO.

@bertdeblock
Copy link
Member

Would it be okay if we close this since we now have #752? Which is in FCP.

@rwjblue rwjblue closed this as completed Nov 11, 2021
@rwjblue
Copy link
Member

rwjblue commented Nov 11, 2021

Thanks @bertdeblock!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests