InversifyJS
InversifyJS copied to clipboard
toService not working for async services
Expected Behavior
At the moment it is possible to define service having asynchronous @postConstruct() method making it asynchronous and it would be great to have it work together with toService binding.
Current Behavior
As toService is doing basically
BindingToSyntax.prototype.toService = function (service) {
this.toDynamicValue(function (context) { return context.container.get(service); });
};
It breaks as getAsync need to be used.
Possible Solution
Add new api method
BindingToSyntax.prototype.toAsyncService = function (service) {
this.toDynamicValue(function (context) { return context.container.getAsync(service); });
};
Steps to Reproduce (for bugs)
import { Container, injectable, multiInject, postConstruct } from 'inversify'
import 'reflect-metadata'
@injectable()
class A {
constructor(@multiInject('X') x) {
console.log(x)
}
}
@injectable()
class B {
@postConstruct()
async init() {}
}
const container = new Container()
container.bind(B).toSelf().inSingletonScope()
container.bind(A).toSelf()
container.bind('X').toService(B)
container.getAsync(A).then(console.log).catch(console.error)
npx ts-node test.ts
Error: You are attempting to construct 'class B {
async init() { }
}' in a synchronous way
but it has asynchronous dependencies.
at Container._getButThrowIfAsync (/home/abramczykg/git/tuatara-finance-platform/tfp-local-development/modules/cli/node_modules/.pnpm/[email protected]/node_modules/inversify/src/container/container.ts:583:13)
at Container.get (/home/abramczykg/git/tuatara-finance-platform/tfp-local-development/modules/cli/node_modules/.pnpm/[email protected]/node_modules/inversify/src/container/container.ts:325:17)
at Binding.dynamicValue (/home/abramczykg/git/tuatara-finance-platform/tfp-local-development/modules/cli/node_modules/.pnpm/[email protected]/node_modules/inversify/src/syntax/binding_to_syntax.ts:96:38)
at /home/abramczykg/git/tuatara-finance-platform/tfp-local-development/modules/cli/node_modules/.pnpm/[email protected]/node_modules/inversify/src/resolution/resolver.ts:51:86
at tryAndThrowErrorIfStackOverflow (/home/abramczykg/git/tuatara-finance-platform/tfp-local-development/modules/cli/node_modules/.pnpm/[email protected]/node_modules/inversify/src/utils/exceptions.ts:12:12)
at _resolveFactoryFromBinding (/home/abramczykg/git/tuatara-finance-platform/tfp-local-development/modules/cli/node_modules/.pnpm/[email protected]/node_modules/inversify/src/resolution/resolver.ts:50:41)
at _getResolvedFromBinding (/home/abramczykg/git/tuatara-finance-platform/tfp-local-development/modules/cli/node_modules/.pnpm/[email protected]/node_modules/inversify/src/resolution/resolver.ts:85:16)
at /home/abramczykg/git/tuatara-finance-platform/tfp-local-development/modules/cli/node_modules/.pnpm/[email protected]/node_modules/inversify/src/resolution/resolver.ts:111:18
at _resolveInScope (/home/abramczykg/git/tuatara-finance-platform/tfp-local-development/modules/cli/node_modules/.pnpm/[email protected]/node_modules/inversify/src/resolution/resolver.ts:100:12)
at _resolveBinding (/home/abramczykg/git/tuatara-finance-platform/tfp-local-development/modules/cli/node_modules/.pnpm/[email protected]/node_modules/inversify/src/resolution/resolver.ts:110:10)
Context
toService binding is useful to bind the same instance in multiple contexts - for example binding a service both to its own class for direct access and to some token for multi-inject.
Your Environment
- Version used: 6.0.1