This is still just an idea, but I think it's very much possible to use a Proxy in combination of CLS to create a truly request-scoped providers in the Nest sense of the word but without the need to recreate the whole provider chain.
The implementation would be is similar to the one of request-scoped beans in the Spring framework for Java.
This would enable the following usage:
@Injectable()
export class UserService {
constructor(
// inject a singleton provider, that is actually a Proxy instance with correctly set up accessor traps
@InjectCls(RequestUser) user: RequestUser
) {}
getCurrentUserName() {
// when accessing the object, we the call is proxied to the current user object in the CLS
return this.user.name
}
}
or even
@Injectable()
export class UserService {
constructor(
// it could be possible to inject arbitrary provider - in this case a connection to the tenant database
@InjectCls('TENANT_CONNECTION') db: Knex
) {}
getCurrentUserFromDb() {
// the call would be again proxied to the current TENANT_CONNENCTION object in the CLS
return this.db.select('whatever').from('users') ...
}
}
The registration of such providers could be done as follows:
imports: [
ClsModule.forFeature(RequestUser)
]
and If we were to support the second use case - that is arbitrary factory providers, then even
It would be needed to figure out where and when to populate the CLS store with the provider. It is too late to do it at the proxy access time, because the provider could be itself async so it would have to have been already constructed at the time of access.
Next issue is how to inject providers and such. All this would probably happen in the enhancer when the CLS context is being set up using moduleRef.
Also, what about situations where we're setting up the CLS store manually with cls.run()?. We'd need to construct the providers there somehow and since the operation must be async, it can't be done in cls.run() directly. We'll probably need an explicit call - something like await cls.boostrapProxyProviders().
This is still just an idea, but I think it's very much possible to use a Proxy in combination of CLS to create a truly request-scoped providers in the Nest sense of the word but without the need to recreate the whole provider chain.
The implementation would be is similar to the one of request-scoped beans in the Spring framework for Java.
This would enable the following usage:
or even
The registration of such providers could be done as follows:
and If we were to support the second use case - that is arbitrary factory providers, then even
It would be needed to figure out where and when to populate the CLS store with the provider. It is too late to do it at the proxy access time, because the provider could be itself async so it would have to have been already constructed at the time of access.
Next issue is how to inject providers and such. All this would probably happen in the enhancer when the CLS context is being set up using moduleRef.
Also, what about situations where we're setting up the CLS store manually with
cls.run()
?. We'd need to construct the providers there somehow and since the operation must be async, it can't be done incls.run()
directly. We'll probably need an explicit call - something likeawait cls.boostrapProxyProviders()
.