-
Notifications
You must be signed in to change notification settings - Fork 25.1k
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
bug: service instantiated eagerly when it has a lifecycle hook #14552
Comments
Eager/lazy initialization is a must for any decent DI impl. But I agree it was a poor design decision to use
So I would say it's a duplicate of #13960 |
Really? Where is that written? I do not know of any DI system that instantiates its services until they are requested. I've been using DI for 15 years. Why would it be OK to wait when there is no What is the value of constructing a service immediately, before it is ever requested? What purpose does that serve? I can't think of a use case. And if I did (and it would be rare), I could achieve the intended effect trivially by immediately injecting the service in the module/component/directive that provided it. Whether decent or indecent, I'm still waiting for an explanation. |
Spring. the most popular java framework. Google Guice also has the ability to eager/lazy initialize services. If you don't have such a use case it doesn't mean nobody hasn't. |
Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. Fixes angular#14552
Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. This also makes all `useValue` providers eager, which should have not observable impact other than code size. Fixes angular#14552
Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. This also makes all `useValue` providers eager, which should have not observable impact other than code size. Fixes angular#14552
BREAKING CHANGE: Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. This also makes all `useValue` providers eager, which should have no observable impact other than code size. EXPECTED IMPACT: Making providers eager was an incorrect behavior and never documented. Also, providers that are used by a directive / pipe / ngModule stay eager. So the impact should be rather small. Fixes angular#14552
BREAKING CHANGE: Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. This also makes all `useValue` providers eager, which should have no observable impact other than code size. EXPECTED IMPACT: Making providers eager was an incorrect behavior and never documented. Also, providers that are used by a directive / pipe / ngModule stay eager. So the impact should be rather small. Fixes angular#14552
BREAKING CHANGE: Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. This also makes all `useValue` providers eager, which should have no observable impact other than code size. EXPECTED IMPACT: Making providers eager was an incorrect behavior and never documented. Also, providers that are used by a directive / pipe / ngModule stay eager. So the impact should be rather small. Fixes angular#14552
BREAKING CHANGE: Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. This also makes all `useValue` providers eager, which should have no observable impact other than code size. EXPECTED IMPACT: Making providers eager was an incorrect behavior and never documented. Also, providers that are used by a directive / pipe / ngModule stay eager. So the impact should be rather small. Fixes angular#14552
BREAKING CHANGE: Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. This also makes all `useValue` providers eager, which should have no observable impact other than code size. EXPECTED IMPACT: Making providers eager was an incorrect behavior and never documented. Also, providers that are used by a directive / pipe / ngModule stay eager. So the impact should be rather small. Fixes angular#14552
BREAKING CHANGE: Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. This also makes all `useValue` providers eager, which should have no observable impact other than code size. EXPECTED IMPACT: Making providers eager was an incorrect behavior and never documented. Also, providers that are used by a directive / pipe / ngModule stay eager. So the impact should be rather small. Fixes #14552
…5070) BREAKING CHANGE: Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. This also makes all `useValue` providers eager, which should have no observable impact other than code size. EXPECTED IMPACT: Making providers eager was an incorrect behavior and never documented. Also, providers that are used by a directive / pipe / ngModule stay eager. So the impact should be rather small. Fixes angular#14552
…5070) BREAKING CHANGE: Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. This also makes all `useValue` providers eager, which should have no observable impact other than code size. EXPECTED IMPACT: Making providers eager was an incorrect behavior and never documented. Also, providers that are used by a directive / pipe / ngModule stay eager. So the impact should be rather small. Fixes angular#14552
…5070) BREAKING CHANGE: Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. This also makes all `useValue` providers eager, which should have no observable impact other than code size. EXPECTED IMPACT: Making providers eager was an incorrect behavior and never documented. Also, providers that are used by a directive / pipe / ngModule stay eager. So the impact should be rather small. Fixes angular#14552
…5070) BREAKING CHANGE: Perviously, any provider that had an ngOnDestroy lifecycle hook would be created eagerly. Now, only classes that are annotated with @component, @directive, @pipe, @NgModule are eager. Providers only become eager if they are either directly or transitively injected into one of the above. This also makes all `useValue` providers eager, which should have no observable impact other than code size. EXPECTED IMPACT: Making providers eager was an incorrect behavior and never documented. Also, providers that are used by a directive / pipe / ngModule stay eager. So the impact should be rather small. Fixes angular#14552
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
I'm submitting a ... (check one with "x")
Current behavior
When a provided service implements the
ngOnDestroy
lifecycle hook (the only LC hook honored by Angular at this point), Angular instantiates the service eagerly with the module/component/directive that creates it. But if the service does not implement this hook, Angular waits and only instantiates it when the service is requested.This is clearly intended behavior. There is a test for it here:
angular/modules/@angular/core/test/linker/ng_module_integration_spec.ts
Line 919 in d169c24
At a minimum we need to document this extraordinary result.
More importantly, I believe this behavior is mistaken on several grounds.
It is inconsistent. Why create in the presence of a destroy method and but not create w/o a destroy method?
Such a service could unintentionally acquire resources and start working when it isn't actually needed at all. Developers don't know about this behavior and won't know that their constructors are called before they are expected to be called.
Adding the destroy hook changes the behavior of the service. A service that was once constructed lazily will now be created eagerly for no apparent reason.
It complicates the service API. There is no easy way to make the service wait until needed before it starts doing potentially expensive initialization work. Folks will have to come up with private protocols to call init on the service or bury the init logic in the methods of the service's public API.
It's not clear that its scope of application is as intended. The behavior appears to have been introduced in connection with NgModules but, per the test and my experience, it applies also when the service is provided to components and directives.
This "feature" appears to have been in the product since August of 2016 (ecdaded) so I can't say that it is a breaking change.
Expected behavior
Please either remove this behavior for Angular v.4 OR explain what good purpose it serves. In the latter case, the documentation should convey this explanation to users so they will understand what is otherwise a mysterious and inconsistent result.
It's still in master.
The text was updated successfully, but these errors were encountered: