how to extend service with dependencies in angular 2

前端 未结 3 1394
野的像风
野的像风 2020-12-14 06:48

I have a parent service which has some dependencies like

@Injectable()
export class ParentService{
  constructor(private http:Http, private customService:Cus         


        
相关标签:
3条回答
  • 2020-12-14 07:13

    If you make the DI services in the abstract class protected and omit the constructor in the subclass, then the services are available in the subclass.

    0 讨论(0)
  • 2020-12-14 07:22

    The parameters of the super class need to be repeated and passed to the super call:

    @Injectable()
    export class ChildService extends ParentService{
      constructor (http:Http, customService:CustomService){
        super(http, customService);
      }
    }
    

    There are some "hacks" to work around like Inheritance and dependency injection

    0 讨论(0)
  • 2020-12-14 07:24

    Simply make base service... non-@Injectable()! For example, you need to supply a method to retrieve user profile in LoginService. This method will be different for different instances of LoginService, and parent class must not know anything about where from this method came: it can be lambda, it can be exported function, it can be a method of another service. To achieve this, you can declare parent service which Parent service:

    // Don't annotate it with @Injectable() ! It's a simple class.
    export abstract class BaseLoginService {
      constructor(
        // This won't be injected automatically, 
        // child class must call super() and provide value for this argument.
        // Note: it's private, can't be accessed outside of BaseLoginService class
        private http: HttpClient,
        // Method used to retrieve user profile
        private profileGetter: () => Observable<UserDetails>, 
        private router: Router
      ) {
        this.profileGetter().subscribe(); // Do something with this method
      }
    

    Then extend it in child class:

    // Child class must be annotated with @Injectable(),
    // if you don't need to extend it further
    @Injectable() 
    export class LoginService extends BaseLoginService {
    
      constructor(
        // Note: no public/private/protected here - "http"
        // will be just an argument
        http: HttpClient, 
        private profileService: ProfileService, // This is the private field of LoginService class
        router: Router,
        // Some service used by LoginService class, parent class BaseLoginService
        // doesn't need to know about SomeOtherService
        private someOtherService: SomeOtherService
      ) {
        super(
          http,
          // Need lambda here to capture profileService instance. If
          // profileService.getUserDetailsMethod doesn't use instance
          // fields or methods, then we can simply write 
          // "profileService.getUserDetailsMethod" (without quotes, obviously).
          () => profileService.getUserDetailsMethod(), 
          router
        );
        this.someOtherService.doSomething(); // Custom initialization code
      }
    

    Note: in providers section of module specify LoginService instead of parent BaseLoginService:

    providers: [
      LoginService,
    

    and use it in component classes:

    export class LoginComponent implements OnInit {
      constructor(
        private loginService: LoginService
      ) {
      }
    

    If you need to use parent service (e.g. in shared components which only need functionality from parent service class), then provide BaseLoginService this way:

    providers: [
      {provide: BaseLoginService, useExisting: LoginService}, // For those components which need functionality from base class only
      LoginService, // Still need this one for those components which need functionality from child class
    
    0 讨论(0)
提交回复
热议问题