[RFC] tegg 支持根据 qualifier 动态注入的能力
<!-- 相关 RFC 示例：https://git.io/fphwy -->

## 背景

目前 tegg 中没有动态注入的能力，无法实现根据运行逻辑去注入。举个例子，我们有两个执行器 HTTPExecutor 和 RpcExecutor，在运行时根据入参去决定使用哪个执行器。

```ts
interface IExecutor {
 execute(args): Promise<void>
}

// 自定义 qualifier
@Executor(ExecutorType.HTTP)
@ContextProto()
class HttpExecutor implement IExecutor {
  execute() {
    // ....
  }
}

@Executor(ExecutorType.RPC)
@ContextProto()
class RpcExecutor  implement IExecutor {
  execute() {
    // ....
  }
}

class Foo {
  @Inject()
  httpExecutor: HttpExecutor;
 
 @Inject()
  rpcExecutor: RpcExecutor;

  request(type) {
    if (type === ExecutorType.HTTP) {
      return this.httpExecutor.execute();
    } else {
      return this.rpcExecutor.execute();
    }
  }
}

```

这样去看代码会发现扩展性较差，当需要新增一种实现，要做两件事情:
- 新增实现类
- 去使用的地方新增一个实现

枚举使用了多少次，就要修改多少次地方，不利于扩展。因此期望可以通过 qualifier 去动态注入，减少修改的地方。

## 思路

```
abstract class AbstractExecutor {
  execute();
}

// 自定义 qualifier
@Executor(ExecutorType.HTTP)
@ContextProto()
class HttpExecutor extends AbstractExecutor {
  execute() {
    // ....
  }
}

@Executor(ExecutorType.RPC)
@ContextProto()
class RpcExecutor  extends AbstractExecutor {
  execute() {
    // ....
  }
}

class Foo {
  @Inject()
  eggObjectFactory: EggObjectFactory;
 
  request(type) {
    const executor: Executor = await this.eggObjectFactory.getObject(Executor, type);
    return executor.execute();
  }
}
```

主要变化:
- 将 `IExecutor` 从一个接口变为一个抽象类 `AbstractExecutor`，原因是 interface 无法挂载元信息，类才可以
- 通过 `EggObjectFactory` 来获取实际的对象，而不是通过静态的注入对象

附接口定义
```ts
interface EggObjectFactory {
  getObject<T>(clazz: abstract new () => T, qualifierValue: QualifierValue);
}
```