title: Provide Dynamic services using string values
body: <p>I'm working on a new library. What I'm trying to achieve here is to give the user the ability to provide any service he wants based on my base service interface, and then I'll use it internally in my library.</p>
  <p>Base Service:</p>
  <pre class="lang-js prettyprint-override"><code>export interface MyBaseServiceDataService {
    getData(): Promise&lt;string[]&gt;;
  }
  </code></pre>
  <p>Injector and Factory:</p>
  <pre class="lang-js prettyprint-override"><code>export function dataServiceProviderFactory&lt;T extends MyBaseServiceDataService&gt;(type: { new(): T; }): T {
    return new type();
  }
  
  export const PROJECT_OPTIONS: InjectionToken&lt;ProjectOptions&gt; =
    new InjectionToken&lt;ProjectOptions&gt;(&quot;PROJECT_OPTIONS&quot;);
  
  
  export interface ProjectOptions {
    dataServices?: Record&lt;string, MyBaseServiceDataService&gt;;
    validationServices?: Record&lt;string, Type&lt;MyBaseServiceDataService&gt;&gt;;
  }
  
  </code></pre>
  <p>How I'm planning to use the above code, the user will create a new service like this:</p>
  <pre class="lang-js prettyprint-override"><code>@Injectable()
  export class OptionDataService implements MyBaseServiceDataService {
  
    async getData(): Promise&lt;string[]&gt; {
      return Promise.reject(&quot;Not implemented&quot;)
    }
  }
  
  </code></pre>
  <p>and then provide blow code in his module:</p>
  <pre class="lang-js prettyprint-override"><code>  providers: [
      {
        provide: PROJECT_OPTIONS,
        useValue: &lt;ProjectOptions&gt;{
          dataServices: {
            options: dataServiceProviderFactory(OptionDataService)
          }
        }
      }]
  </code></pre>
  <p>internally I will call it using my service.</p>
  <pre class="lang-js prettyprint-override"><code>@Injectable()
  export class LoaderService {
  
    private options: ProjectOptions = {}
  
    constructor(@Optional() @Inject(PROJECT_OPTIONS) injector: ProjectOptions) {
      if(injector)
        this.options = injector
    }
  
    getDataService(serviceName: string): Promise&lt;string[]&gt; {
      if (!this.options.dataServices)
        return Promise.reject(&quot;Data services provider is not provided&quot;)
      if (this.options.dataServices[serviceName] === undefined)
        return Promise.reject(`Service ${serviceName} is not provided`)
      return this.options.dataServices[serviceName].getData()
    }
  }
  </code></pre>
  <p>Everything is working fine, but I found an issue if the user tries to provide an external service like <code>HttpClient</code> on his own service, the factory is not accepting any constructor,</p>
  <pre class="lang-js prettyprint-override"><code>@Injectable()
  export class OptionDataService implements MyBaseServiceDataService {
  
    constructor(private http: HttpClient) {
      console.log(http);
    }
  
    async getData(): Promise&lt;string[]&gt; {
      return Promise.reject(&quot;Not implemented&quot;)
    }
  }
  
  </code></pre>
  <p>even though I changed my factory to something like this</p>
  <pre class="lang-js prettyprint-override"><code>export function dataServiceProviderFactory&lt;T extends Type&lt;MyBaseServiceDataService&gt;&gt;(type: T, ...args: any[]): MyBaseServiceDataService {
    return new type(...args);
  }
  </code></pre>
  <p>the instance of <code>HttpClient</code> will be undefined on the service, I'm expecting to receive <code>HttpClient</code> instance from dependency injection, so what I'm missing?</p>