Repository navigation
Support scope annotations on injectable constructor parameters and fields - #1949
davidboden wants to merge 2 commits into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
b21340d to
bb7ec65
Compare
|
Possibly a candidate for https://github.com/GuicedEE/Services/tree/master/Google/guice-core ? (guicedee.com) |
Allows @singleton and other @ScopeAnnotation-annotated annotations to be applied directly to an injectable constructor's parameters, so the same dependency can be scoped locally to that constructor without requiring a separate binding declaration. Also fixes the error ordering when a constructor parameter's scope annotation is not bound: the "no scope is bound" error is now reported before Guice attempts to resolve the dependency's binding, rather than being masked by a misleading "no injectable constructor" error.
bb7ec65 to
ad2d7ac
Compare
Extends the existing constructor-parameter scoping support so that scope annotations (e.g. @singleton, @RequestScoped) can also target FIELD, allowing field-local scoping for injected dependencies. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Happy to take guidance. I'll take a look at the GuicedEE project; thanks for the pointer. |
|
@davidboden Sorry misunderstood - gave it an attempt - GuicedEE/Services#77 |
Status
This is a draft PR intended as a discussion point. The API and implementation are open to revision based on maintainer feedback.
Motivation
A dependency may already have an unscoped binding or provider, while one particular consumer needs that dependency to follow a narrower lifecycle. For example, a class may want one dependency instance per request without making every injection of that dependency request-scoped.
Today that generally requires declaring another provider or private binding in a module solely to add the scope. This proposal allows the consumer to express the requirement directly, either on an injectable constructor parameter or on an injected field:
An injectable constructor or class already describes how Guice provides the containing class and which dependencies that provision requires. Allowing the constructor parameter or field to define additional behavior for those dependencies can remove module boilerplate while keeping the scope requirement next to the code that relies on it.
Proposed behavior
Scope annotations on injectable constructor parameters or injected fields create a local scoped provider around the dependency's existing binding.
For
@Singleton, the dependency therefore appears singleton only to objects created through that constructor, or only for that field. For@RequestScoped, it is reused by that constructor or field within one request and recreated in a later request.The implementation uses the normal Guice scope registration and provider machinery, so custom scopes are supported when their annotations:
@ScopeAnnotationorjakarta.inject.Scope;PARAMETERorFIELD(as applicable) in their target; andbindScopewhere required.This PR adds
PARAMETERandFIELDsupport to Guice's@Singletonand servlet@RequestScopedannotations. Method injection and provider-method parameters are unchanged.Existing diagnostics are retained: multiple scope annotations on one parameter or field are rejected, and an unregistered custom scope reports
No scope is bound to ....Tests
Coverage is included for:
Full build validation is still in progress while this remains a draft.
Discussion points
(consuming constructor or field, scope annotation, dependency key)the right cache boundary?MisplacedScopeAnnotationscheck assumes scope annotations on parameters or fields are ineffective. Adopting this syntax would require that check to recognize the new Guice behavior, or users would need a narrow suppression.