We’ve been using the Macwire dependency injection framework and I recently got to use the tagging functionality for the first time. This was a great feature that enabled me to instantiate multiple instances of the same type and have the framework differentiate between the instances when choosing which to inject.
First, you define a trait to be the marker; it doesn’t need anything in it. Then, at the injection site it becomes
BaseType @@ Marker
When setting up the initial site, instead of being
That’s all there is to the base case. You can chain multiple tags in a couple of different ways.
wire[BaseType].taggedWith[Marker with OtherMarker]
I combined all of this with another neat construction of the type system.
trait Foo[Marker](dependency:Bar @@ Marker)
Once I set up the Foo type like this it lets me take a marked dependency in a generic way.
I would like to see some sort of syntax like
So I don’t need to make changes to the type being instantiated in order to control the preference of what instance gets supplied. There is also the module syntax, where you can create a module for each set and then nest those modules to get the injections as desired; but I don’t want to have to organize my code in a specific way in order to have it work correctly.
All of this had me thinking about currying/partial application and the application of generic types. You can take a type with multiple generic parameters and apply some of them and leave the rest for later. It’s not something that happens often but it came to mind with the way I was using generic types there and it was an interesting insight into the symmetry between types and data.