Repository: angular
Issue: asynchronous providers
Labels: feature,area: core,core: di,feature: under consideration

<!--
PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.

ISSUES MISSING IMPORTANT INFORMATION MAY BE CLOSED WITHOUT INVESTIGATION.
-->

## I'm submitting a...
<!-- Check one of the following options with "x" -->
<pre><code>
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  <!-- Please search GitHub for a similar issue or PR before submitting -->
[ 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
</code></pre>

## Current behavior
<!-- Describe how the issue manifests. -->
Angular doesn't seem to support providers which asynchronously create their object / service. For those who want to load config from a server dynamically, they seem to be encouraged to use a kludge comprised of creating a `ConfigService` and then using `APP_INITIALIZER` to delay the bootstrapping just long enough to make an async call and inject the results into the `ConfigService`. But, this is a hack, and is buggy with race conditions - the `ConfigService` may potentially be injected into other services, and be used / read from before this bootstrapping happens, causing bugs because the object gets used before it's ready.

Here's a plunk which demonstrates the problem: https://plnkr.co/edit/plWAT5i5BFtjastSdaVy?p=preview

Notice the problem is that another service will read from the `ConfigService` before it's truly finished being "constructed" IMO, since we need to construct the object, and then finish initializing it's state the `APP_INITIALIZER` step. I think reading config in a constructor is pretty common programming practice.

## Expected behavior
<!-- Describe what the desired behavior would be. -->
I think it would be great to be able to do something like:

```
export function asyncConfigServiceFactory(api: ApiService) {
    return new Promise((resolve, reject) => {
        api.get('my-config.json').then(response => {
            resolve(new ConfigService(response));
        });
    });
}

@NgModule({
  providers: [
    ApiService,
    {
      provide: ConfigService,
      useAsyncFactory: asyncConfigServiceFactory,
      deps: [ApiService]
    },
  ],
})
```
(notice the `useAsyncFactory` idea to tell ng that it should wait on the promise, and use the value it produces as the service) 
I think that's a pretty straight forward way to do it, but whatever you think is the best way to address it.

## What is the motivation / use case for changing the behavior?
<!-- Describe the motivation or the concrete use case. -->

My use case is to fetch config from a server, and stick it into a service, and then inject this `ConfigService` into other services. I do not want to inject `ConfigService` into other stuff until it's fully constructed and ready to be used - in other words, until the asynchronous request to the server has completed and my `ConfigService` has all the values populated into it.

I've seen quite a few other users trying to accomplish the same thing on Stackoverflow. This kludge is becoming the defacto way to do it, and SO answers are getting highly upvoted, and multiple articles are being published on other websites - all recommending a bug-prone method. That's not good for the framework's reputation long term. It should be easy to do it "the right way", whatever that is.

## Environment

<pre><code>
Angular version: 5.1
<!-- Check whether this is still an issue in the most recent Angular version -->


Others:
<!-- Anything else relevant?  Operating system version, IDE, package manager, HTTP server, ... -->
</code></pre>

Other issues that would be well served by async providers:
https://github.com/angular/angular/issues/19448  
https://github.com/angular/angular/issues/20383