<p dir="auto"><strong>I'm submitting a ...</strong>  (check one with "x")</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="[x] bug report =&gt; search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request =&gt; Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question"><pre class="notranslate"><code class="notranslate">[x] bug report =&gt; search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request =&gt; Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
</code></pre></div>
<p dir="auto"><strong>Current behavior</strong></p>

<p dir="auto">When a provided service implements the <code class="notranslate">ngOnDestroy</code> 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.</p>
<p dir="auto"><strong>This is clearly intended behavior</strong>. There is a test for it here:<br>
</p><div class="Box Box--condensed my-2">
  <div class="Box-header f6">
    <p class="mb-0 text-bold">
      <a href="https://github.com/angular/angular/blob/d169c2434e3b5cd5991e38ffd8904e0919f11788/modules/%40angular/core/test/linker/ng_module_integration_spec.ts#L919">angular/modules/@angular/core/test/linker/ng_module_integration_spec.ts</a>
    </p>
    <p class="mb-0 color-fg-muted">
         Line 919
      in
      <a data-pjax="true" class="commit-tease-sha" href="/angular/angular/commit/d169c2434e3b5cd5991e38ffd8904e0919f11788">d169c24</a>
    </p>
  </div>
  <div itemprop="text" class="Box-body p-0 blob-wrapper blob-wrapper-embedded data">
    <table class="highlight tab-size mb-0 js-file-line-container" data-tab-size="8" data-paste-markdown-skip="">

        <tbody><tr class="border-0">
          <td id="L919" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="919"></td>
          <td id="LC919" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> <span class="pl-k">let</span> <span class="pl-s1">created</span> <span class="pl-c1">=</span> <span class="pl-c1">false</span><span class="pl-kos">;</span> </td>
        </tr>
    </tbody></table>
  </div>
</div>
<p></p>
<p dir="auto">At a minimum we need to document this extraordinary result.</p>
<blockquote>
<p dir="auto">p.s. We also need to add documentation about <code class="notranslate">ngOnDestroy</code> in the regular docs; that is already on the docs' todo list.</p>
</blockquote>
<p dir="auto">More importantly, I believe this behavior is mistaken on several grounds.</p>
<ol dir="auto">
<li>
<p dir="auto">It is inconsistent. Why create in the presence of a destroy method and but not create w/o a destroy method?</p>
</li>
<li>
<p dir="auto">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.</p>
</li>
<li>
<p dir="auto">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.</p>
</li>
<li>
<p dir="auto">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.</p>
</li>
<li>
<p dir="auto">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.</p>
</li>
</ol>
<p dir="auto">This "feature" appears to have been in the product since August of 2016 (<a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/angular/angular/commit/ecdaded25f949385987a7ab89573b5aca2befa4e/hovercard" href="https://github.com/angular/angular/commit/ecdaded25f949385987a7ab89573b5aca2befa4e"><tt>ecdaded</tt></a>) so I can't say that it is a breaking change.</p>
<p dir="auto"><strong>Expected behavior</strong></p>

<p dir="auto">Please either remove this behavior for Angular v.4  <strong>OR</strong> 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.</p>
<ul dir="auto">
<li><strong>Angular version:</strong> 2.4.X (since RC5)</li>
</ul>

<p dir="auto">It's still in master.</p>
<p dir="auto">Currently we can eager initialize a service by adding <code class="notranslate">ngOnDestroy</code> hook, but:</p>
<ol dir="auto">
<li>Very few people know that services can have <code class="notranslate">ngOnDestroy</code> (afaik it's still not documented on angular.io).</li>
<li>Even less know that if <code class="notranslate">ngOnDestroy</code> is present, service will be initialized eagerly.</li>
<li>We don't always have a disposal logic, so we are forced to add an empty <code class="notranslate">ngOnDestroy</code> method with a comment so it won't be remove by accident.</li>
</ol>
<p dir="auto">According to <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="199326190" data-permission-text="Title is private" data-url="https://github.com/angular/angular/issues/13820" data-hovercard-type="issue" data-hovercard-url="/angular/angular/issues/13820/hovercard" href="https://github.com/angular/angular/issues/13820">#13820</a> in 4.x <code class="notranslate">@Injectable</code> will be mandatory, so I think it will be more intuitive to control instantiation via annotation <code class="notranslate">@Injectable({lazy: false})</code></p>