Closed synkarius closed 1 year ago
@synkarius I agree that it'd be great to have a built in solution for this, it's something I miss from Zenject. I do have a slightly different approach to temporally solve this that might be useful to you:
const tokens = {
listToken: token<IExample[]>('IExample[]'),
e1: token<IExample>('example1'),
e2: token<IExample>('example2'),
e3: token<IExample>('example3'),
};
const demoContainer = new Container();
// bind e1, e2, e3 however
demoContainer.bind(listToken)
.toInstance(() => [
demoContainer.get(tokens.e1),
demoContainer.get(tokens.e2),
demoContainer.get(tokens.e3),
])
.inSingletonScope(); //or whatever appropriate
This is still a bit imperfect, but it feels a bit more connected. The one thing that would make this a lot better is if factory methods received the requesting container, because it would allow for more flexible definition of factories in dependency modules. Currently there doesn't seem to be an easy way to do this kind of construction with demoContainer
being a demoModule
and the container is elsewhere.
I don't know if it is feasible for the way brandi does things, but the way Zenject handles this is to allow multiple things to be bound to the same requirement (basically bound to the same token). If you request an IExample
, it'd just give you the first of them (I think.. it's been a second) but if you ask for a List<IExample>
it collects all matching bound items and supplies them. Super duper handy for injecting collected strategies and adapters into a consuming bit of business logic.
@polerin The thing I don't like about this solution is that it requires tokens e1
-e3
to be bound before listToken
can be bound, which partially defeats the purpose of using a DI lib. (After all, couldn't you just use constructor injection with no DI lib if you're forced to bind things in order?)
The Zenject 2nd-binding-to-token-is-array thing sounds pretty clean though.
@polerin The thing I don't like about this solution is that it requires tokens
e1
-e3
to be bound beforelistToken
can be bound, which partially defeats the purpose of using a DI lib. (After all, couldn't you just use constructor injection with no DI lib if you're forced to bind things in order?)The Zenject 2nd-binding-to-token-is-array thing sounds pretty clean though.
Technically e1..e3 just have to be bound before the container.get(listToken) call is made, as toInstance() is evaluated lazily by default.
Ah. I didn't realize toInstance
was evaluated lazily. That seems fine then.
First of all, let me say that this is an awesome library and I'm enjoying using it very much.
This is a feature request. If I'm understanding the docs correctly, currently, if I want to inject a class with an array of things, I have to do something like this to get the array injectable:
This gets the job done, but it would be nice if there were a smoother mechanism. In particular, this line is kind of ugly:
I don't want to be too specific about how that gets accomplished except to say that specifying the precise tokens of the injected array items is maybe less slick than marking them all somehow and then providing the marker to
injected
or some function like it.