Thoughts on Providers - microbean/microbean-settings GitHub Wiki
See Thoughts On Paths for some background.
A Provider
bears qualifiers, but they're…inherited or nested or something. They're…more or less specific. This is where I'm still hazy.
(In the current work on the v3
branch, a Provider
itself doesn't bear qualifiers, but reports whether or not it could potentially satisfy demand represented by a Context
.)
The easiest case is the most general. A Provider
that somehow reports that it makes Car
objects, full stop, is, as you can tell intuitively, ridiculously general. What kind of Car
? For what kind of demand? For whom? In what use cases?
The best example of a Provider
that does this today is ServiceLoader
. You ask for a Car
; the ServiceLoader
looks up com.foo.bar.Car
entries in /META-INF/services/
locations and loads whatever it finds there and typically offers up the first thing. Maybe you thought you were getting a Porsche but instead you get a base-level Toyota. These kinds of providers are good for absolute globals, of which there are very few in practice. This gets into the subject of qualified applications, and what configuration is, but that's for another Wiki page.
Now imagine a ServiceLoader
that could understand that the Car
in question was "in the context of" an existing Household
. Perhaps it would serve up a different one. That's a Provider
in a nutshell.
So Provider
s can be more or less specific, for one. A Provider
that "answers the phone" for car.getDrivetrain().getEngine().getCylinder(0)
is more specific in some currently unspecified way than one that just "answers the phone" for Cylinder
, or one that "answers the phone" for Engine.class/Cylinder.class:accessor=getCylinder;arg0=0
. So once you clear the type bar (a Car
provider doesn't provide Wheel
s) specificity has some connection to the length of a path as well as the number and values of qualifiers.
Where things might get tricky (let's just stick to artificial length-of-1 paths for a moment):
- Demand is for
/Car.class:value=myFavorite
. Providers include one forCar.class
andCar.class:value=myDailyDriver
. The first provider should be used, maybe? with a warning? or no providers. - Demand is for
/:env=test/Car.class:value=myFavorite
. Providers are as above but also one forCar.class
-with-the-additional-stipulation-that-the-application-is-qualified-with-env=test
(ah, a notation gap). Here, this latter provider should be used.