Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow inject annotation on records #35

Open
h908714124 opened this issue Dec 15, 2023 · 2 comments
Open

Allow inject annotation on records #35

h908714124 opened this issue Dec 15, 2023 · 2 comments

Comments

@h908714124
Copy link

h908714124 commented Dec 15, 2023

The following is invalid:

@Inject
record Heater(Logger logger) {
    void heat() {
        logger.log("~ ~ ~ heating ~ ~ ~");
    }
}

To make it work, we have to convert the record to a class and annotate the constructor instead:

final class Heater {
    private final Logger logger;
    @Inject 
    Heater(Logger logger) {
        this.logger = logger;
    }
    void heat() {
        logger.log("~ ~ ~ heating ~ ~ ~");
    }
}

This is tedious. We should be able to inject into records, it would be equivalent to constructor injection.

Currently the @Inject annotation has @Target({ METHOD, CONSTRUCTOR, FIELD }). I think if we add TYPE to that list, then the annotation would be allowed on records too and injection frameworks like dagger and spring can start supporting that. TYPE has been around since 1.5, so a Java version update would not be necessary.

@manovotn
Copy link

From CDI perspective (as a consumer of this annotation), just allowing to use it on types would cause ambiguity for other cases.
This is because a type may have arbitrary number of constructors and at most one at a time should have @Inject for container to know how to instantiate given class.
We would need to add some javadoc either explaining how this works with types in general or say that it's only taken into account for records.
CC @Ladicek

@h908714124 also, I assume this can be workarounded in your framework by declaring the compact constructor and annotating it? That should be a usage within bounds of current specification text.

    record Heater(Logger logger) {

        @Inject
        public Heater {
        }
        
        void heat() {
            // some code...
        }
    }

@Ladicek
Copy link
Contributor

Ladicek commented Jan 2, 2024

Yeah, annotating an empty compact constructor is the way to go here.

It is not very intuitive, because the constructor parameters are declared in the record header, but Java doesn't provide any syntax to annotate the record constructor without actually declaring the constructor. (Kotlin does, see e.g. https://kotlinlang.org/docs/annotations.html#usage, but it's not exactly pretty either in my opinion.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants