-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] 精简 core 对外透出的装饰器 #190
Comments
负面影响: 对于同一实现需要覆盖时,需要用户主动使用 Id 机制替代,如 RFC 例中的 Logger,此前允许用户通过下述代码获得唯一的 Logger: @DefineLogger()
class InternalLogger implements Logger {}
@DefineLogger()
class ExternalLogger implements Logger {}
// --
@Inject(ArtusInjectEnum.Logger)
logger: Logger; 在完成改动后,下述场景必须明确注入: @Injectable()
class InternalLogger {}
@Injectable()
class ExternalLogger {}
// ---
@Inject()
logger: InternalLogger;
// or
@Inject()
logger: ExternalLogger;
// or
@Inject()
logger: ArtusLogger; 如仍需达成覆盖效果,必须由上层用户自己定义 Id(或保留 Artus 内的 Symbol): const LOGGER_SYMBOL = Symbol.for('logger');
@Injectable({ id: LOGGER_SYMBOL })
class InternalLogger implements Logger {}
@Injectable({ id: LOGGER_SYMBOL })
class ExternalLogger implements Logger {}
// ---
@Inject(LOGGER_SYMBOL)
logger: Logger; |
这种确实也是问题,id + 基类,可以做到近似同一份虚拟类 + 不同实现的能力 |
@hyj1991 框架覆盖下层的一个实现这个的用户编程界面是怎么样的,这个点我也是有点疑惑的,最近在想 common-bin 如何实现继承覆盖 |
不过这里是否可以改成: @Injectable({ id: Logger })
class InternalLogger extends Logger {}
@Injectable({ id: Logger })
class ExternalLogger extends Logger {}
// --
@Inject()
logger: Logger; |
@atian25 我比较倾向于上面的用法,Inject 靠
|
一般我们在底层写基础框架和插件的时候,不会特意去指定 ID 吧?这样会不会有点繁琐,即如果希望被上层覆盖,底层就必须处处写 id ?(我没有倾向性,只是想看看哪个更好) |
@atian25 关于这一点,core 里不需要指定单独的装饰器只提供基类以供使用,有必要的话可以在上层框架透出类似的装饰器包一层 |
不过这个问题也许可以转换为:
|
而且这里的 id 指定,只有对应的 Logger 插件开发者或者上层框架开发者才需要感知,应用层的用户就是统一 // 此处的 Logger 是基类
@Inject()
logger:: Logger 所以我认为是否没有必要在 core 中提供冗余的语法糖类装饰器,保持 core 的纯净 |
感觉没回答上天猪的问题??我也有同样的问题,想被覆盖的都得明确提供 id ,这样上层才能使用这个 id 去覆盖吧? |
我对 ioc 的用法还不是很熟悉。在我那个 bin 的场景下,假设我在 egg-bin 有一个 service,会提供给某个 command 使用。
对应的伪代码大概怎么样? PS:spring 好像是在底层声明 ID? |
// egg-bin
@Injectable()
export class CommonService {
}
// @ali/egg-bin
@Injectable({ id: CommonService })
export class AliCommonService extends CommonService {
} 这样 egg-bin 中 Inject CommonService 拿到的就是 AliCommonService 实例了 |
用常量覆盖,带来的不便就是既需要关注常量 id,还需要指定类型: @Inject(COMMON_SERVICE)
service: CommonService |
昨天看了下 @JerrysShan 在新的 injection 实现中,默认会把 class type 也作为容器 key 写入,这样天然就可以支持 |
嗯,这种写法在继承的情况下可以接受。 另外,如果我是全新写一个 Service 不继承原来的,也需要 import 原来的 Service 来作为 ID 是吧? |
要看是不是要覆盖,我理解覆盖的场景都是同一个基类,多个不同的实现,并且 Inject 的地方不是自己控制的,这样才会有这种需求。 如果是上面描述的这钟需要覆盖原来实现的,就需要 id |
可以保留基类,去除 application 上的引用,上游继承后直接
Inject
基类或者实现类来通过 IoC 的标准形式进行引入。The text was updated successfully, but these errors were encountered: