lance-p
lance-p

Reputation: 1070

Angular Dependency Injection - Why is imports needed?

In the code sample below, app.module sets the providers to use for Angular dependency injection. Angular, therefore has a reference to the DataService class.

// app.module.ts 
import { DataService } from './services/dataService';
import { LocationsComponent } from './components/locations.component';
@NgModule({
  declarations: [
    AppComponent,
    LocationsComponent,
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
  ],
  providers: [
    DataService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

My understanding is that in locations.component Angular will perform the DI to create a new instance of the DataService class in the constructor. What I don't understand is why import { DataService } is needed in the component? Why can't Angular provide this DataService instance to the constructor when it see the DataService type specified in the constructor since Angular knows from app.module where to find the DataService class? The import { DataService } in locations.component seems redundant.

// locations.component.ts
import { DataService } from '../../../services/dataService';
@Component({
  selector: 'app-locations',
  templateUrl: './locations.component.html'
})
export class LocationsComponent {
  data: any[] = [];
  constructor(private dataService: DataService) { 
      this.data = dataService.load();
  }
}

Upvotes: 0

Views: 515

Answers (1)

Igor
Igor

Reputation: 62238

I think I understand your question. It is not why are imports needed but it is:

Why do you have to specify the same import 2x, once at the point of use (component) and once in the module declaration.

You technically don't have to specify the import of the service at all in the module. The @Component attribute can take an option providers value and you can specify what the dependencies are for the component. If you do that you do not have to declare the same service in the module as a dependency in the module.

import { DataService } from '../../../services/dataService';
@Component({
  selector: 'app-locations',
  templateUrl: './locations.component.html',
  providers: [DataService],

})
export class LocationsComponent {
  data: any[] = [];
  constructor(private dataService: DataService) { 
      this.data = dataService.load();
  }
}

The reason you specify it at the module is to register the service in the module with the angular dependency injection framework. Otherwise you would have to do the above (register at component level) each time you want to inject that same type. By registering that type at the module level it also will inject the same instance of the service, effectively creating a singleton-like pattern.

Upvotes: 1

Related Questions