Angular2 DI: How to inject dependency under @NgModule?
<p><strong>TL;DR 25.10.16: update</strong></p>

<p>I renamed the title to provide more clarification as i am still concerned about the right solution.</p>

<p>Given a module</p>

<pre><code>@NgModule({
  imports: [
    ExternalModule.forRoot(config),
  ],
  providers: [EXTERNAL_PROVIDERS(config)],
})
export class MyModule{}
</code></pre>

<p>So my questions are: is there any possibilty that i can inject a dependency with my passed config like this ?</p>

<ol>
<li><code>ExternalModule.forRoot(@Inject(MyConfig) config : MyConfig)</code></li>
<li><code>providers: [EXTERNAL_PROVIDERS(@Inject(MyConfig) config)]</code>  (</li>
</ol>

<p>I do not want to create <code>{provide: xxx, deps :[xxx], useFactory : xxx}</code> for each given external provider.</p>

<p>I tried to initialize a <code>Application Wide Service Locator</code> with access to the root injector as described <a href="https://stackoverflow.com/questions/39409328/storing-injector-instance-for-use-in-components">here</a> , but with Angular 2.1.0 <code>ngDoBootstrap</code> does not work as expected.</p>

<h2>----------</h2>

<p><strong>Old Post:</strong></p>

<p>I would like to know what the correct pattern is for configuring an external third party library provider in Angular2.</p>

<p>Let's take an example (code samples in Typescript):</p>

<p>There is a library that exposes its providers and offers some configuration options by <code>config</code> object literal:</p>

<pre><code>export function THIRD_PARTY_PROVIDERS(config = {}): Provider[] {
  return [
    {
      provide: ExtConfigurableService,
      deps: [Http],
      useFactory: (http: Http) =&gt; {
        return new ExtConfigurableService(http, config);
      }
    },
    ExtOtherService
  ];
}
</code></pre>

<p>Then on the client side, these providers can be included in an <code>@NgModule</code>:</p>

<pre><code>@NgModule({
  providers: [
    THIRD_PARTY_PROVIDERS({foo : 'bar'})
  ],
})
export class ClientModule { }
</code></pre>

<p>But what if my configuration object itself has dependencies on an existent service like <code>MyService</code>?
I cannot inject a dependency in the providers array. The only way from my point of view is to use a <a href="https://angular.io/docs/ts/latest/api/core/index/FactoryProvider-interface.html" rel="nofollow noreferrer">FactoryProvider</a>: </p>

<pre><code>const myConfigProvider = {
    provide: MyConfig,
    deps: [MyService],
    useFactory: (MyService) =&gt; {
      return new MyConfig(MyService);
    }
  };
</code></pre>

<p>Given that, how can i inject <code>MyConfig</code> into <code>THIRD_PARTY_PROVIDERS</code>? </p>

<hr>

<p>The only solutions which i came up with are not satisfactory:</p>

<ol>
<li>Use of an exported <code>OpaqueToken</code> from the third party provider side like <a href="https://github.com/angular/angular/blob/master/modules/%40angular/router/src/router_module.ts" rel="nofollow noreferrer">here (Angular 2 Router)</a></li>
<li>configure all providers manuallay from the client side</li>
</ol>

<p>The first can only be done from the third party provider: export the token and require that token as own dependency in the factory provider.</p>

<p>The second is very ugly, because you have to know and configure the implementation details / services of the third party lib by yourself. </p>

<pre><code>@NgModule({
      providers: [
        {provide: ExtConfigurableService, deps: [MyConfig], useFactory: ...},
        ExtOtherService
      ],
    })
    export class ClientModule { }
</code></pre>

<p>What is the preferred pattern in angular 2 (client and third party provider side)?</p>

<hr>

<p><strong>Update 19.10.16</strong></p>

<p>I implemented my first proposal for a solution and it works fine. But it requires that you have <strong>control over the external library / agree with the project owner on your changes or fork the repo</strong>.</p>

<p>third-party-lib.ts:</p>

<pre><code>   export const JWT_CONFIGURATION = new OpaqueToken('THIRD_PARTY_PROVIDER_TOKEN');
    ...

    @Injectable()
    export class ExtConfigurableService {

      constructor(@Inject(JWT_CONFIGURATION) config: any) {
        // do someting with client provided config 
      }
</code></pre>

<p>my-module.ts</p>

<pre><code> @NgModule({
      providers: [
        {
        provide: JWT_CONFIGURATION,
        deps: [MyService],
        useFactory: (mySvc: MyService) =&gt; {
          return {foo : 'bar'};
        }, THIRD_PARTY_PROVIDERS
      ]
    })
    export class MyModule { }
</code></pre>

<p>But if the external lib requires you to pass your config as an argument (like in the example at the top), i still don't know how to inject myconfig into it.</p>

<p>Has Angular 2 other ways to inject a dependency with <code>@Inject()</code> in addition to the constructor or the factory provider?</p>