You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Feature: allow inject() to be used in constructor #25039
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:
Current behavior
All the dependencies must be injected in constructor:
@Injectable()
export class MyService {
constructor(private myOtherSerivice: MyOtherService) {}
}
Expected behavior
Allow to use inject() function when object is constructed, for example:
Minimal reproduction of the problem with instructions
N/A
What is the motivation / use case for changing the behavior?
Imagine You have an abstract class which is extended by many services or components.
Then You want to change it which requires adding a new dependency.
When injecting via constructor You would have modify EVERY class that inherits it.
Environment
Angular version: 6.0.3
Reacted by Trotyl Yu, Alex Malkevich, Максим Иванов, Toni Villena, Alexander Turtsevich, Bram Gotink and Harpush
@kemsky I know but it feels like a hack and You still need to inject Injector which may require a change in existing code base. With inject() approach it would be possible to create (as a library) decorator that uses reflections or create TypeScript transformer to achieve something like this:
@Injectable()
export class MyService {
@Autowire() private myOtherSerivice: MyOtherService;
}
This is indeed the correct behavior with current default provider semantics. Given this pattern is mostly about consumer-side usage, so it's should not be restricted to default provider, but also constructor of component, directive, pipe and directive provider should be supported as well.
Given Ivy is going to be fully context-based (instead of call stack-based), I guess this will be supported in Ivy by default (haven't checked yet).
EDIT: have a quick look at current Ivy codes, which should indeed work for most scenarios as long as powered by factorymethod function property of ngXXXDef, like:
So the constructor would always share the same context of the factory.
Given this is already the case in Ivy, should be reasonable to bring it (back?) to view engine.
EDIT Again for Ivy: one thing possibly needs to be noticed is the inconsistency between inject and directiveInject, the private services like ElementRef, ViewContainerRef would not be available in inject (by default).
Likely this behavior would be fixed by #23330, which would make inject() for directives different than inject() for application-wide services.
@dawidgarus Static injector, module injector and node injector are mostly unrelated, and what used in a normal application are only module injector and node injector, not static injector.
Also, the creation of Component, Directive, Pipe, NgModule is not the job of any injector.
Hopefully ivy will make everything simpler, because right now contributing to angular core by an outsider is, for all intents and purposes, impossible. Is there a public document which describes in details how angular internals work? For example what ngfactory file structure is exactly?
Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.
We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.
You can find more details about the feature request process in our documentation.
Wow, injection via decorators sounds great! Just out of curiosity: since I still won't be able to get the cdron demand I'd need to inject it (via decorator) in all of my components. Could this have a noticable performance impact? Or is it like No, the CDR exists anyway for every component, you wouldn't even be able to measure it?
angular-automatic-lock-bot commented on Jun 5, 2022
Activity
kemsky commentedon Jul 23, 2018
Actually it is possible to inject Injector and call its get-methods in your parent constructor.
dawidgarus commentedon Jul 23, 2018
@kemsky I know but it feels like a hack and You still need to inject Injector which may require a change in existing code base. With
inject()approach it would be possible to create (as a library) decorator that uses reflections or create TypeScript transformer to achieve something like this:trotyl commentedon Jul 24, 2018
@kemsky This is more about consistency, using
inject()is already supported at service constructor (with module-level provider):https://stackblitz.com/edit/angular-dergtr?file=src%2Fapp%2Fapp.component.ts
This is indeed the correct behavior with current default provider semantics. Given this pattern is mostly about consumer-side usage, so it's should not be restricted to default provider, but also constructor of component, directive, pipe and directive provider should be supported as well.
Given Ivy is going to be fully context-based (instead of call stack-based), I guess this will be supported in Ivy by default (haven't checked yet).
EDIT: have a quick look at current Ivy codes, which should indeed work for most scenarios as long as powered by
factorymethodfunction property ofngXXXDef, like:So the
constructorwould always share the same context of thefactory.Given this is already the case in Ivy, should be reasonable to bring it (back?) to view engine.
EDIT Again for Ivy: one thing possibly needs to be noticed is the inconsistency between
injectanddirectiveInject, the private services likeElementRef,ViewContainerRefwould not be available ininject(by default).Likely this behavior would be fixed by #23330, which would make
inject()for directives different thaninject()for application-wide services.trotyl commentedon Jul 27, 2018
Seems a little hard for current view engine, I'd suggest just waiting for Ivy.
@vicb Possibly add a
fixed by Ivytag for better tracking?gund commentedon Jul 27, 2018
I think this should really be fixed because right now DI behaviour is inconsistent.
If a service that is provided in
@Componenttries to injectViewContainerRefit will not get it unless the component itself injects it.Repro: https://stackblitz.com/edit/angular-jxyoet
trotyl commentedon Jul 27, 2018
REMOVED.
gund commentedon Jul 27, 2018
@trotyl I do not think I am able to create a PR since I have not enough knowledge of how DI resolution mechanics are implemented.
I hope that in Ivy this will be fixed tho (#23330).
dawidgarus commentedon Jul 27, 2018
@trotyl Correct me if I'm wrong, but wouldn't simple change in StaticInjector be sufficient?
Just wrap
get()method body with something like this:trotyl commentedon Jul 30, 2018
@dawidgarus Static injector, module injector and node injector are mostly unrelated, and what used in a normal application are only module injector and node injector, not static injector.
Also, the creation of
Component,Directive,Pipe,NgModuleis not the job of any injector.dawidgarus commentedon Jul 30, 2018
Hopefully ivy will make everything simpler, because right now contributing to angular core by an outsider is, for all intents and purposes, impossible. Is there a public document which describes in details how angular internals work? For example what ngfactory file structure is exactly?
trotyl commentedon Jul 30, 2018
This is going to be a built-in feature in Ivy and no need to worry about.
I guess it's not a good idea to ask another outsider then.
angular-robot commentedon Jun 4, 2021
Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.
Find more details about Angular's feature request process in our documentation.
angular-robot commentedon Jun 25, 2021
Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.
We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.
You can find more details about the feature request process in our documentation.
alxhub commentedon May 4, 2022
Closing as a duplicate of #34425 (they are the same underlying request)
angelaki commentedon May 5, 2022
Wow, injection via decorators sounds great! Just out of curiosity: since I still won't be able to get the
cdron demand I'd need to inject it (via decorator) in all of my components. Could this have a noticable performance impact? Or is it like No, the CDR exists anyway for every component, you wouldn't even be able to measure it?angular-automatic-lock-bot commentedon Jun 5, 2022
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.