<HTML><BODY>I thought here, and would like to share my ideas hoping to get comments from<br>more experienced people.<br><br>First of all I came to conclusion that CDI works badly with cases when we need<br>to change field values in super classes. If there is a lot of inheritance as in my case:<br>ParentA, ChildA0, ChildA1.., ParentB, ChildB0, ChildB1..,... then situation is<br>becoming very bad. Maybe in future there will be other solutions in CDI specs.<br><br>I found two additional ways that can be used. 1) Inject not beans but instances,<br>+ method SimpleFoo newFoo {return Instance<SimpleFoo>.get} + overriding. <br>2) Inject BeanManager + method SimpleFoo newFoo() {beanManager...} + overriding.<br><br>Maybe such ways can be named lazy/postponed initialization with overriding support....<br><br>Best regards, Alex<br><br><br><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;">
        Вторник, 29 августа 2017, 18:22 +03:00 от Martin Kouba <mkouba@redhat.com>:<br>
        <br>
        <div id="">
        
<div class="js-helper js-readmsg-msg">
        <style type="text/css"></style>
        <div>
                <base target="_self" href="https://e.mail.ru/">
                
<div id="style_15040201450000000908_BODY">Hi Alex,<br>
<br>
that's an interesting question. Indeed, qualifiers are the way to go if <br>
you need to keep the method signature.<br>
<br>
Another way could be to override the setFoo() method so that the Child <br>
initializer is ignored and add a new method to inject AdvancedFoo:<br>
<br>
@Override<br>
protected void setFoo(SimpleFoo foo) { // Do nothing }<br>
<br>
@Inject<br>
void setAdvancedFoo(AdvancedFoo foo) {<br>
super.setFoo(foo);<br>
}<br>
<br>
However, note that right now there are the following beans:<br>
<br>
SimpleFoo with bean types Object, SimpleFoo<br>
AdvancedFoo -> Object, SimpleFoo, AdvancedFoo<br>
<br>
So if you do @Inject SimpleFoo you get ambiguous dependency exception <br>
because both SimpleFoo and AdvancedFoo are eligible for injection.<br>
<br>
To resolve this you need to use qualifiers or restrict the bean types of <br>
AdvancedFoo:<br>
<br>
@Typed(AdvancedFoo.class)<br>
class AdvancedFoo extends SimpleFoo {}<br>
<br>
HTH<br>
<br>
Martin<br>
<br>
<br>
Dne 29.8.2017 v 15:09 Matej Novotny napsal(a):<br>
> Hi Alex,<br>
> <br>
> no need to be sorry, you have come to the right place :)<br>
> As for your question, the simplest thing is probably to use qualifiers.<br>
> <br>
> Create your own like this:<br>
> <br>
> @Qualifier<br>
> @Retention(RetentionPolicy.RUNTIME)<br>
> @Target({ ElementType.TYPE, ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD })<br>
> public @interface MyQualifier {}<br>
> <br>
> <br>
> And then change your AdvancedFoo class to use the qualifier:<br>
> <br>
> @Dependent<br>
> @MyQualifier<br>
> public class AdvancedFoo extends SimpleFoo {<br>
> }<br>
> <br>
> And accordingly, the init method which uses injection should then look like this:<br>
> <br>
> @Dependent<br>
> public class Parent extends Child {<br>
> <br>
> @Inject<br>
> @Override<br>
> protected void setFoo(@MyQualifier SimpleFoo foo) {<br>
> super.setFoo(foo);<br>
> }<br>
> }<br>
> <br>
> Does this answer your question?<br>
> <br>
> Matej<br>
> <br>
> ----- Original Message -----<br>
>> From: "Alex Sviridov" <<a href="mailto:ooo_saturn7@mail.ru">ooo_saturn7@mail.ru</a>><br>
>> To: "weld-dev" <<a href="mailto:weld-dev@lists.jboss.org">weld-dev@lists.jboss.org</a>><br>
>> Sent: Tuesday, August 29, 2017 1:46:23 PM<br>
>> Subject: [weld-dev] How to make method injection when bean subclass is required in Weld?<br>
>><br>
>> Hi all,<br>
>><br>
>> I am really sorry for writing to this mailing list, but I checked all user<br>
>> forums and chats and saw that they are very old.<br>
>><br>
>> I would be very thankful if someone gives suggestion for solving the<br>
>> following problem.<br>
>> I have a child and parent class. Child has SimpleFoo, Parent needs Advaced<br>
>> foo. So,<br>
>><br>
>> @Dependent<br>
>> public class SimpleFoo {<br>
>> }<br>
>><br>
>> @Dependent<br>
>> public class AdvancedFoo extends SimpleFoo {<br>
>> }<br>
>><br>
>> @Dependent<br>
>> public class Child {<br>
>><br>
>> private SimpleFoo foo;<br>
>><br>
>> @Inject<br>
>> protected void setFoo(SimpleFoo foo) {<br>
>> this.foo = foo;<br>
>> }<br>
>> }<br>
>><br>
>> @Dependent<br>
>> public class Parent extends Child {<br>
>><br>
>> @Inject<br>
>> @Override<br>
>> protected void setFoo(SimpleFoo foo) { //How to inject here AdvancedFoo?<br>
>> super.setFoo(foo);<br>
>> }<br>
>> }<br>
>><br>
>> How to inject in Parent AdvancedFoo? I know that I can do it via constructor<br>
>> injection<br>
>> but I need method injection. How to do it? Can it be done without using names<br>
>> (like MyBean1)<br>
>> but only using classes (AdvancedFoo)?<br>
>><br>
>> Best regards, Alex<br>
>><br>
>><br>
>><br>
>><br>
>><br>
>> --<br>
>> Alex Sviridov<br>
>><br>
>> _______________________________________________<br>
>> weld-dev mailing list<br>
>> <a href="mailto:weld-dev@lists.jboss.org">weld-dev@lists.jboss.org</a><br>
>> <a href="https://lists.jboss.org/mailman/listinfo/weld-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/weld-dev</a><br>
> _______________________________________________<br>
> weld-dev mailing list<br>
> <a href="mailto:weld-dev@lists.jboss.org">weld-dev@lists.jboss.org</a><br>
> <a href="https://lists.jboss.org/mailman/listinfo/weld-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/weld-dev</a><br>
> <br>
<br>
-- <br>
Martin Kouba<br>
Senior Software Engineer<br>
Red Hat, Czech Republic<br>
</div>
                <base target="_self" href="https://e.mail.ru/">
        </div>
        
</div>
</div>
</blockquote>
<br></BODY></HTML>