<HTML><BODY>Hi Matej<br><br>Thank you for your comment. However, note, that I wrote foo = newFoo() but not foo = new Foo();<br>By other words foo is created in newFoo method, but not calling new operator.<br><br>Best regards, Alex<br><br><br><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;">
        Среда, 30 августа 2017, 12:45 +03:00 от Matej Novotny <manovotn@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_15040863160000000233_BODY">Hi Alex<br>
<br>
What you suggest will inevitably fail for the reasons we mentioned previously.<br>
Both approaches will try to resolve a bean of type SimpleFoo which is ambiguous.<br>
<br>
Furthermore, doing `foo = new Foo()` is like saying "goodbye CDI".<br>
If you do this, you control the lifecycle of such object, not CDI.<br>
Therefore, there will be no injection done into such object, neither will CDI be able to dispose of such object.<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: Wednesday, August 30, 2017 11:10:27 AM<br>
> Subject: Re: [weld-dev] How to make method injection when bean subclass is required in Weld?<br>
> <br>
> <br>
> <br>
> Hi Matej,<br>
> <br>
> I meant the following (in previous example I had a mistake - called Parent<br>
> Child and Child Parent)<br>
> , now without this mistake:<br>
> 1)<br>
> public class Parent {<br>
> <br>
> @Inject<br>
> private Instance<SimpleFoo> fooInstance;<br>
> <br>
> private SimpleFoo foo;<br>
> <br>
> protected SimpleFoo newFoo() {<br>
> return fooInstance.get();<br>
> }<br>
> <br>
> @PostConstruct<br>
> private void doPostConstruct() {<br>
> foo = newFoo();<br>
> }<br>
> }<br>
> <br>
> public class Child extends Parent {<br>
> <br>
> @Inject<br>
> private Instance<AdvancedFoo> fooInstance;<br>
> <br>
> @Override<br>
> protected AdvancedFoo newFoo() {<br>
> return fooInstance.get();<br>
> }<br>
> }<br>
> <br>
> <br>
> 2)<br>
> <br>
> public class Parent {<br>
> <br>
> @Inject<br>
> protected BeanManager beanManager;<br>
> <br>
> private SimpleFoo foo;<br>
> <br>
> protected SimpleFoo newFoo() {<br>
> SimpleFoo foo = constructing bean with BM;<br>
> return foo;<br>
> }<br>
> <br>
> @PostConstruct<br>
> private void doPostConstruct() {<br>
> foo = newFoo();<br>
> }<br>
> }<br>
> <br>
> public class Child extends Parent {<br>
> <br>
> @Override<br>
> protected AdvancedFoo newFoo() {<br>
> AdvancedFoo foo = constructing bean with BM;<br>
> return foo;<br>
> }<br>
> }<br>
> <br>
> Thank you for your explanation of Typed. I got it.<br>
> <br>
> Best regards, Alex<br>
> <br>
> <br>
> Среда, 30 августа 2017, 10:51 +03:00 от Matej Novotny <<a href="mailto:manovotn@redhat.com">manovotn@redhat.com</a>>:<br>
> <br>
> 1) If you inject Instance<T>, you still have the ambiguous dependency issue<br>
> for any class which does have a subclass.<br>
> E.g. from your sample:<br>
> <br>
> @Inject<br>
> Instance<SimpleFoo> instance;<br>
> <br>
> //within some method<br>
> instance.get(); -> this will blow up because you have two beans which have<br>
> SimpleFoo type (SimpleFoo and AdvancedFoo)<br>
> <br>
> 2) I don't understand what you mean by this. How does BM help here?<br>
> <br>
> <br>
> Sidenote:<br>
> You might want to try and use what Martin said - limiting the types of a bean<br>
> with @Typed(MyClass.Foo).<br>
> That way you have control over the bean types and can further manupulate the<br>
> injection.<br>
> Limit all your children to only the actual subclass type they have:<br>
> <br>
> @Dependent<br>
> @Typed(AdvancedFoo.class)<br>
> public class AdvancedFoo extends SimpleFoo {<br>
> // this ben now only has a bean of AdvancedFoo, e.g. it does not fit into<br>
> injection point for SimpleFoo<br>
> }<br>
> <br>
> And then override the initializer methods like this:<br>
> <br>
> @Dependent<br>
> public class Parent extends Child {<br>
> <br>
> @Inject<br>
> @Override<br>
> protected void setFoo(AdvancedFoo foo) {<br>
> this.foo = foo; // assuming foo is a protected field<br>
> }<br>
> }<br>
> <br>
> Matej<br>
> <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 8:54:47 PM<br>
> > Subject: Re: [weld-dev] How to make method injection when bean subclass is<br>
> > required in Weld?<br>
> > <br>
> > I thought here, and would like to share my ideas hoping to get comments<br>
> > from<br>
> > more experienced people.<br>
> > <br>
> > First of all I came to conclusion that CDI works badly with cases when we<br>
> > need<br>
> > to change field values in super classes. If there is a lot of inheritance<br>
> > as<br>
> > in my case:<br>
> > ParentA, ChildA0, ChildA1.., ParentB, ChildB0, ChildB1..,... then situation<br>
> > is<br>
> > becoming very bad. Maybe in future there will be other solutions in CDI<br>
> > specs.<br>
> > <br>
> > I found two additional ways that can be used. 1) Inject not beans but<br>
> > instances,<br>
> > + method SimpleFoo newFoo {return Instance<SimpleFoo>.get} + overriding.<br>
> > 2) Inject BeanManager + method SimpleFoo newFoo() {beanManager...} +<br>
> > overriding.<br>
> > <br>
> > Maybe such ways can be named lazy/postponed initialization with overriding<br>
> > support....<br>
> > <br>
> > Best regards, Alex<br>
> > <br>
> > <br>
> > <br>
> > <br>
> > Вторник, 29 августа 2017, 18:22 +03:00 от Martin Kouba < <a href="mailto:mkouba@redhat.com">mkouba@redhat.com</a><br>
> > >:<br>
> > <br>
> > 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,<br>
> > > 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<br>
> > > like<br>
> > > 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<br>
> > >> required in Weld?<br>
> > >> <br>
> > >> Hi all,<br>
> > >> <br>
> > >> I am really sorry for writing to this mailing list, but I checked all<br>
> > >> 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<br>
> > >> 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<br>
> > >> constructor<br>
> > >> injection<br>
> > >> but I need method injection. How to do it? Can it be done without using<br>
> > >> 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>
> > <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>
> <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>
</div>
                <base target="_self" href="https://e.mail.ru/">
        </div>
        
</div>
</div>
</blockquote>
<br></BODY></HTML>