-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Qute: access to beans without name in qute templates #41932
Comments
You added a link to a Zulip discussion, please make sure the description of the issue is comprehensive and doesn't require accessing Zulip This message is automatically generated by a bot. |
/cc @mkouba (qute) |
So if I understand it correctly it's not about access to named beans but about access to beans with no name. I will change the title of the issue. Feel free to update the title if needed. |
I dislike the I propose to expand the
|
👎 I think that it's a misuse of the syntax. Qute ref guide is pretty clear that the dot notation is used to access properties or call (virtual) methods. Also it would not work for parameterized types; e.g. if there's a bean with type If we want to support unnamed beans in templates it should be clear that we're doing a type lookup, e.g. something like |
That documentation can be updated :)
We could argue that those require the longer alternative
I could get behind
That's easy, the resolution rules are: |
I like this solution where when you want something not named, you lookup. The others seem more hacky and confusing (having yet another namespace). |
By the way, we completely missed the CDI qualifiers. Which is not an uncommon thing in CDI apps. And qualifiers can have binding members. This all makes the lookup a lot more complex. In other words, all the proposed solutions would only solve some of the use cases. I will repeat my answer from the zulip discussion: @Named
public class Names {
@Inject
UserInfo userInfo;
public UserInfo userInfo() {
return userInfo;
}
} and then |
🤷 |
If there is a bean @ApplicationScoped
@PayBy(CHEQUE)
public class UserInfo {
} Then you can't simply do The workaround proposed would require a minimal change: @Named
public class Names {
@Inject
@PayBy(CHEQUE)
UserInfo userInfo;
public UserInfo userInfo() {
return userInfo;
}
} |
While I would prefer allowing access by type name, I can accept the time is not yet right. But when I see code like this: @Named
public class Names {
@Inject
@PayBy(CHEQUE)
UserInfo userInfo;
public UserInfo userInfo() {
return userInfo;
}
} It feels like boilerplate. The method has no purpose beyond a name. The field is only there to specify a qualifier. So… hear me out for a shorter proposal: @Named
public record NamedCdiBeans(@PayBy(CHEQUE) UserInfo userInfo) {
} Where the record is just a placeholder for things that can be named and have qualifiers. WDYT? Interfaces or classes work too: @Named
public class NamedCdiBeans {
@PayBy(CHEQUE)
UserInfo userInfo;
} @Named
public interface NamedCdiBeans {
@PayBy(CHEQUE)
UserInfo userInfo();
} But at least here, we don't have boilerplate (beyond the group): we attach names to CDI types (and qualifiers) and nothing superfluous can be removed. |
The Java record works if you add a valid scope @Singleton
@Named
public record NamedCdiBeans(@PayBy(CHEQUE) UserInfo userInfo) {
} Note The workaround with The class works if you add a scope and make the field @Singleton
@Named
public class NamedCdiBeans {
@PayBy(CHEQUE) // this will require @Inject if quarkus.arc.auto-inject-fields=false
public UserInfo userInfo;
} The |
Oh, so, when you say they work, you mean they do produce a valid named bean for |
Of course not! It works in the sense that you can use the named bean to access the injected bean - you need to use the name first, i.e. |
Pls read the note in my comment ;-). |
Ah, so we could do something better then, and find a way to make them available without naming the container… Something like: @NamedContainer
public record NamedCdiBeans(@PayBy(CHEQUE) UserInfo userInfo, Something something) {
} Which would translate (semantically) to:
|
Hm, this would require additional validation - to verify the beans are available, to verify there are no duplicate names, etc. Also it would not allow users to specify a different name, e.g. another annotation would be required if you want to use I do understand the need to associate an existing bean with a name (without @Ladicek @manovotn guys do you have an idea because it could be a more general CDI feature. |
I'm sure you already have validation for that.
Same, I'm sure you already validate that.
Of course you can specify a different name, by changing the name of the parameter :) @NamedContainer
public record NamedCdiBeans(@PayBy(CHEQUE) UserInfo uInfo, Something something) {
} |
If you make |
One more thing. I'm not sure if I understand correctly, but if you want @NamedContainer
public record Names(@PayBy(CHEQUE) UserInfo uInfo, Something something) {
} to let you write If you want |
+1 for named stereotype with a default scope as that will naturally trigger all our validations. |
I'd say at that point you can have annotation transformer (or CDI extension) adding the |
Yeah, exactly. I just realized we already have one external source of metadata. I wouldn't want to add another. |
Yes, extensions have that possibility. We're talking about user code. And yes, that's what Stef and others want - to be able to access beans that have no name and So we need a simple API that would be translated into an annotation transformer. |
@FroMage We do but only if it's used as regular CDI constructs... which is not the case here.
Ah, yes, That would work.
|
CDI Lite extension?
Plus the service provider entry of course. You are then free to name all the beans that you don't own in any way you like. But frankly speaking, the workaround with records is IMO even better - sure, you need to use |
If that works, I agree that's totally fine. But… you're saying this already works ATM? @Stereotype
@Named
@Singleton
public @interface NamedContainer {}
@NamedContainer
public record Names(@PayBy(CHEQUE) UserInfo uInfo, Something something) {
} And I can do |
You can do And yes, the stereotype should just work. It's effectively: @Named
@Singleton
public record Names(@PayBy(CHEQUE) UserInfo uInfo, Something something) {
} |
Well, that's very nice! We should document that, and/or provide the stereotype annotation (if we can find a good name). Does this work for you, @maxandersen @ia3andy ? |
Hm, yes we should definitely document this. I'll send a PR later today. As for the stereotype - maybe something like @TemplateBeans
public record User(@PayBy(CHEQUE) UserInfo info, Something something) {
} And in the template |
|
What if we instead of using a new stereotype simply state that if @Named // @Singleton added automatically
public record User(@PayBy(CHEQUE) UserInfo info, Something something) {
} So there's no need for a new annotation name? |
Works for me :) |
That might interfere with user defined beans that they just put Then again, we could also just keep the bean |
How could it interfere? If you annotate a record with
I will use |
Ugh, don't mind me. For some reason I thought we pick up class based beans even if they only declare a qualifier 🤷
Yea, that sounds good 👍 |
- so that it can be easily used as an intermediate CDI bean for beans that are not annotated with jakarta.inject.Named - related to quarkusio#41932
I've sent a PR: #43775 |
- so that it can be easily used as an intermediate CDI bean for beans that are not annotated with jakarta.inject.Named - related to quarkusio#41932
- so that it can be easily used as an intermediate CDI bean for beans that are not annotated with jakarta.inject.Named - related to quarkusio#41932
Description
when using qute web templates or even plain qute templates default beans without a name is not accessible.
i.e. in java code I can do
@Inject UserInfo user;
but not possible in Qute.You can do tricks like:
but after zulip discussion: https://quarkusio.zulipchat.com/#narrow/stream/187038-dev/topic/qute.20web.20.2F.20how.20to.20.40named.20default.20beans.3F/near/451771103 suggestion on supporting things like the following:
if user not available as parameter inject it.
OR explicit inject in header
OR enhance {cdi:} to support
to look at build time provided names/types.
Implementation ideas
No response
The text was updated successfully, but these errors were encountered: