title: Provide Component with a service instance that depends on component @Input
body: <p>I have a Master-Detail component that contains children grid and detail components.</p>
  
  <p>Based on an @Input entityType parameter, the grid and the detail components will need to initialize their specific dataService property to DataService1, DataService2, ... or DataServiceN.
  What would be the best way to achieve this ? I see various possibilities:</p>
  
  <ol>
  <li><p>Create an <code>@Injectable</code> factory service with a <code>createServiceInstance(entityType)</code> method:</p>
  
  <pre><code>public createService(type: EntityType): any {
      switch (type) {
          case EntityType.Type1:
              return new DataService1();
          case EntityType.Type2:
              return new DataService2();
          case EntityType.TypeN:
              return new DataServiceN();
      }
  }
  </code></pre>
  
  <p>Then inject that service into Master-Detail Component constructor and assign do</p>
  
  <pre><code>this.dataService = this.factoryService.createService(entityType)
  </code></pre>
  
  <p>in ngOnInit / ngOnChanges. We then add @Input dataService to grid and detail components and bind it to masterDetail dataService property.</p></li>
  <li><p>Use an Injector service in detail/grid components, have the providers property of @Component decorator set to [DataService1, DataService2, ..., DataServiceN] and then in ngOnInit do</p>
  
  <pre><code>this.dataService = this.injector.get(getDataService(entityType))
  </code></pre>
  
  <p>with</p>
  
  <pre><code>export function getDataService(entityType: string): any {
      switch (type) {
          case EntityType.Type1:
              return DataService1;
          case EntityType.Type2:
              return DataService2;
          case EntityType.TypeN:
              return DataServiceN;
      }
  }
  </code></pre></li>
  <li><p>Use a mix of 1) and 2) : provide ServiceFactory with [DataService1, DataService2, ..., DataServiceN] in its constructor, then in detail/grid component ngOnInit do</p>
  
  <pre><code>this.dataService = this.factoryService.getDataService(entityType)
  </code></pre>
  
  <p>with</p>
  
  <pre><code>getDataService(entityType: string): any {
      switch (type) {
          case EntityType.Type1:
              return this.dataService1;
          case EntityType.Type2:
              return this.dataService2;
          case EntityType.TypeN:
              return this.dataServiceN;
      }
  }
  </code></pre></li>
  <li><p>Another solution?</p></li>
  </ol>
  
  <p>I'm using Angular 4 with TypeScript.</p>