【问题标题】:Angular 2 Dependency Injection - Inject object independantly of constructorAngular 2 依赖注入 - 独立于构造函数注入对象
【发布时间】:2016-09-16 19:45:53
【问题描述】:

假设我有以下课程:

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

Teachers 是这样创建的:

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

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

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

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

  1. 有一个记录器或

  2. 知道如何构建记录器

我真正想做的是:

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

有没有办法可以做到这一点?

【问题讨论】:

标签: angular dependency-injection


【解决方案1】:

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);
  }
}

【讨论】:

    【解决方案2】:

    我想你正在寻找这个:

    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);
        }
        ...
       }
     ...
    }
    

    【讨论】:

    • 遗憾的是,new Teacher(...).
    • 我不知道你到底想做什么。我的理解是,您希望您的 Logger 成为一个可选依赖项,因为您需要使用 @Optional() 在构造函数中注释记录器。
    • 该问题解释了应该如何使用教师课程。注入器会从您的示例中抛出 Teacher 类,因为其他构造函数注释(公共名称:字符串,私有年龄:数字)不是提供者。
    猜你喜欢
    • 2016-12-30
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    • 2018-12-03
    • 2016-04-28
    • 1970-01-01
    相关资源
    最近更新 更多