tsyringe
tsyringe copied to clipboard
Is is possible to resolve function parameters?
I want to do something like this
class Foo {}
class Bar {}
function fooBar(foo: Foo, bar: Bar){
return () => {
// can use foo and bar instances
}
}
const fb = container.resolve(fooBar)
I can do this, but I don't like [Foo, Bar]
part.
function resolveFunction<T extends any[], R>(fn: (...x: T) => R,
deps: {[K in keyof T]: InjectionToken<T[K]>}): R {
const r = deps.map(container.resolve)
return fn(...(r as any))
}
const x = resolveFunction((foo: Foo, bar: Bar) => ..., [Foo, Bar])
Is is possible to do something better?
Sounds like you want to retrieve parameter-less a handle to a new function which you can execute as if it were your function fooBar(...)
?
Something like:
@injectable()
function fooBar(foo: Foo, bar: Bar) {
// do stuff with foo and bar
}
const injected = container.resolve(fooBar);
injected(); // Does stuff
Currently the answer is no, the @injectable
decorator (and others) does not support this.
However, I think this is totally possible and would be willing to accept a PR for such a feature =]
Unfortunately, functions cannot be decorated in TypeScript currently. I went to implement this, but ran quickly into that wall.
@MeltingMosaic Could class static method be used?
class Factory {
@injectable
static fooBar(foo: Foo, bar: Bar) {
// do stuff with foo and bar
}
}
~~It's possible. I've done it in my own fork of a di container. In https://github.com/nebez/good-injector-async you can find examples of method invocation. See here for a test/example: https://github.com/nebez/good-injector-async/commit/b6ae71d4e3e5c730f6736f3fcea3550d3dbf190d#diff-9d05ba8fe85bfcbf71d6b2ab8a6e8b06R13-R16~~
~~Willing to take this on if nobody else has the appetite for it.~~
edit: ah, misunderstood. This is for functions not instance methods.
Would a non-decorator solution to this be acceptable in a PR?
@hartror, could you provide some pseudocode that might give an example of how you would implement this?
I think it very important. Would you have solution for this?
Still not possible?