Angular 2依赖注入 - 独立于构造函数注入对象

时间:2016-09-16 19:45:54

标签: angular dependency-injection

假设我有以下课程:

export class Teacher {
    constructor( public name: String, private age: number ){}
    ...
}

Teacher是这样创建的:

const firstGradeTeacher: Teacher = new Teacher("Hannah", 32);

我想现在为老师添加一个记录器。记录器为Injectable()。我的第一个想法是做到这一点:

export class Teacher {
    constructor( public name: String, private age: number, private logger: Logger ){}
    ...
}

不幸的是,这意味着现在每个构建教师的人都需要:

  1. 拥有记录器或

  2. 知道如何构建记录器

  3. 我真正喜欢做的是:

    export class Teacher {
        private logger: Logger = Injector.get(); // <-- Does this exist?
        constructor( public name: String, private age: number){}
        ...
    }
    

    我有办法做到这一点吗?

2 个答案:

答案 0 :(得分:2)

使用a hack可以访问根注入器。

但是,这表示XY问题。该类应该是可注射的或不可注射的。混合这些概念并不是一个好主意,因为在Angular中没有惯用的方法。

非注射类工厂是解决这个问题的好方法。

@Injectable()
class TeacherFactory {
  constructor(private logger: Logger) {}

  public createInstance(...args) {
    const teacher = new Teacher(...args);

    // or pass it as extra argument if logger is used in Teacher constructor
    teacher.logger = this.logger;

    return teacher;
  }
}

@Component({
  ...
  providers: [TeacherFactory]
})
class SomeComponent {
  constructor(private teacherFactory: TeacherFactory){
    const firstGradeTeacher: Teacher = teacherFactory.createInstance("Hannah", 32);
  }
}

或者

// non-injectable class
class TeacherFactory {}

@Component({
  ...
  providers: [{ 
    provide: TeacherFactory,
    deps: [Logger],
    useFactory: (logger: Logger) => (...args) => {
      const teacher = new Teacher(...args);
      teacher.logger = logger;

      return teacher;
    }
  }]
})
class SomeComponent {
  constructor(private teacherFactory: TeacherFactory){
    const firstGradeTeacher: Teacher = teacherFactory("Hannah", 32);
  }
}

答案 1 :(得分:-1)

我认为你正在寻找这个:

import { Optional } from '@angular/core';

export class Teacher {
   constructor(public name: String, private age: number, @Optional() private   logger: Logger) {
     if (this.logger) {
       this.logger.log(some_message);
    }
    ...
   }
 ...
}