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 Providers 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 Wheels) 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 for Car.class and Car.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 for Car.class-with-the-additional-stipulation-that-the-application-is-qualified-with-env=test (ah, a notation gap). Here, this latter provider should be used.