Make caching aware of injected services
This commit introduces snapshotting of injected services. Whenever a rule is going
to use a service, we need to know what "state" from this service is relevant (that
is to say, is a rule input) so that we can properly cache the rule whenever the
service changes. For component metadata supplier rules, the rule may use a repository
resource accessor, which is repository based. This means that a rule must be cached
based on the repository it was applied from. For this we introduced a `ValueSnapshottable`
interface that services (or other Gradle classes) may implement if they are snapshottable,
that is to say part or all of their state participate in a cache key.