Hi, yea you are right, I mis-read that. My bad. Anyway, the ambiguous dep. problem still holds true and you have to use another approach.
Let us know if @Typed solves your problem or if we should try and find another solution. Matej ----- Original Message ----- > From: "Alex Sviridov" <[email protected]> > To: "weld-dev" <[email protected]> > Sent: Wednesday, August 30, 2017 11:55:11 AM > Subject: Re: [weld-dev] How to make method injection when bean subclass is > required in Weld? > > Hi Matej > > Thank you for your comment. However, note, that I wrote foo = newFoo() but > not foo = new Foo(); > By other words foo is created in newFoo method, but not calling new operator. > > Best regards, Alex > > > > > Среда, 30 августа 2017, 12:45 +03:00 от Matej Novotny <[email protected]>: > > Hi Alex > > What you suggest will inevitably fail for the reasons we mentioned > previously. > Both approaches will try to resolve a bean of type SimpleFoo which is > ambiguous. > > Furthermore, doing `foo = new Foo()` is like saying "goodbye CDI". > If you do this, you control the lifecycle of such object, not CDI. > Therefore, there will be no injection done into such object, neither will CDI > be able to dispose of such object. > > Matej > > ----- Original Message ----- > > From: "Alex Sviridov" < [email protected] > > > To: "weld-dev" < [email protected] > > > Sent: Wednesday, August 30, 2017 11:10:27 AM > > Subject: Re: [weld-dev] How to make method injection when bean subclass is > > required in Weld? > > > > > > > > Hi Matej, > > > > I meant the following (in previous example I had a mistake - called Parent > > Child and Child Parent) > > , now without this mistake: > > 1) > > public class Parent { > > > > @Inject > > private Instance<SimpleFoo> fooInstance; > > > > private SimpleFoo foo; > > > > protected SimpleFoo newFoo() { > > return fooInstance.get(); > > } > > > > @PostConstruct > > private void doPostConstruct() { > > foo = newFoo(); > > } > > } > > > > public class Child extends Parent { > > > > @Inject > > private Instance<AdvancedFoo> fooInstance; > > > > @Override > > protected AdvancedFoo newFoo() { > > return fooInstance.get(); > > } > > } > > > > > > 2) > > > > public class Parent { > > > > @Inject > > protected BeanManager beanManager; > > > > private SimpleFoo foo; > > > > protected SimpleFoo newFoo() { > > SimpleFoo foo = constructing bean with BM; > > return foo; > > } > > > > @PostConstruct > > private void doPostConstruct() { > > foo = newFoo(); > > } > > } > > > > public class Child extends Parent { > > > > @Override > > protected AdvancedFoo newFoo() { > > AdvancedFoo foo = constructing bean with BM; > > return foo; > > } > > } > > > > Thank you for your explanation of Typed. I got it. > > > > Best regards, Alex > > > > > > Среда, 30 августа 2017, 10:51 +03:00 от Matej Novotny < [email protected] > > >: > > > > 1) If you inject Instance<T>, you still have the ambiguous dependency issue > > for any class which does have a subclass. > > E.g. from your sample: > > > > @Inject > > Instance<SimpleFoo> instance; > > > > //within some method > > instance.get(); -> this will blow up because you have two beans which have > > SimpleFoo type (SimpleFoo and AdvancedFoo) > > > > 2) I don't understand what you mean by this. How does BM help here? > > > > > > Sidenote: > > You might want to try and use what Martin said - limiting the types of a > > bean > > with @Typed(MyClass.Foo). > > That way you have control over the bean types and can further manupulate > > the > > injection. > > Limit all your children to only the actual subclass type they have: > > > > @Dependent > > @Typed(AdvancedFoo.class) > > public class AdvancedFoo extends SimpleFoo { > > // this ben now only has a bean of AdvancedFoo, e.g. it does not fit into > > injection point for SimpleFoo > > } > > > > And then override the initializer methods like this: > > > > @Dependent > > public class Parent extends Child { > > > > @Inject > > @Override > > protected void setFoo(AdvancedFoo foo) { > > this.foo = foo; // assuming foo is a protected field > > } > > } > > > > Matej > > > > > > ----- Original Message ----- > > > From: "Alex Sviridov" < [email protected] > > > > To: "weld-dev" < [email protected] > > > > Sent: Tuesday, August 29, 2017 8:54:47 PM > > > Subject: Re: [weld-dev] How to make method injection when bean subclass > > > is > > > required in Weld? > > > > > > I thought here, and would like to share my ideas hoping to get comments > > > from > > > more experienced people. > > > > > > First of all I came to conclusion that CDI works badly with cases when we > > > need > > > to change field values in super classes. If there is a lot of inheritance > > > as > > > in my case: > > > ParentA, ChildA0, ChildA1.., ParentB, ChildB0, ChildB1..,... then > > > situation > > > is > > > becoming very bad. Maybe in future there will be other solutions in CDI > > > specs. > > > > > > I found two additional ways that can be used. 1) Inject not beans but > > > instances, > > > + method SimpleFoo newFoo {return Instance<SimpleFoo>.get} + overriding. > > > 2) Inject BeanManager + method SimpleFoo newFoo() {beanManager...} + > > > overriding. > > > > > > Maybe such ways can be named lazy/postponed initialization with > > > overriding > > > support.... > > > > > > Best regards, Alex > > > > > > > > > > > > > > > Вторник, 29 августа 2017, 18:22 +03:00 от Martin Kouba < > > > [email protected] > > > >: > > > > > > Hi Alex, > > > > > > that's an interesting question. Indeed, qualifiers are the way to go if > > > you need to keep the method signature. > > > > > > Another way could be to override the setFoo() method so that the Child > > > initializer is ignored and add a new method to inject AdvancedFoo: > > > > > > @Override > > > protected void setFoo(SimpleFoo foo) { // Do nothing } > > > > > > @Inject > > > void setAdvancedFoo(AdvancedFoo foo) { > > > super.setFoo(foo); > > > } > > > > > > However, note that right now there are the following beans: > > > > > > SimpleFoo with bean types Object, SimpleFoo > > > AdvancedFoo -> Object, SimpleFoo, AdvancedFoo > > > > > > So if you do @Inject SimpleFoo you get ambiguous dependency exception > > > because both SimpleFoo and AdvancedFoo are eligible for injection. > > > > > > To resolve this you need to use qualifiers or restrict the bean types of > > > AdvancedFoo: > > > > > > @Typed(AdvancedFoo.class) > > > class AdvancedFoo extends SimpleFoo {} > > > > > > HTH > > > > > > Martin > > > > > > > > > Dne 29.8.2017 v 15:09 Matej Novotny napsal(a): > > > > Hi Alex, > > > > > > > > no need to be sorry, you have come to the right place :) > > > > As for your question, the simplest thing is probably to use qualifiers. > > > > > > > > Create your own like this: > > > > > > > > @Qualifier > > > > @Retention(RetentionPolicy.RUNTIME) > > > > @Target({ ElementType.TYPE, ElementType.PARAMETER, ElementType.FIELD, > > > > ElementType.METHOD }) > > > > public @interface MyQualifier {} > > > > > > > > > > > > And then change your AdvancedFoo class to use the qualifier: > > > > > > > > @Dependent > > > > @MyQualifier > > > > public class AdvancedFoo extends SimpleFoo { > > > > } > > > > > > > > And accordingly, the init method which uses injection should then look > > > > like > > > > this: > > > > > > > > @Dependent > > > > public class Parent extends Child { > > > > > > > > @Inject > > > > @Override > > > > protected void setFoo(@MyQualifier SimpleFoo foo) { > > > > super.setFoo(foo); > > > > } > > > > } > > > > > > > > Does this answer your question? > > > > > > > > Matej > > > > > > > > ----- Original Message ----- > > > >> From: "Alex Sviridov" < [email protected] > > > > >> To: "weld-dev" < [email protected] > > > > >> Sent: Tuesday, August 29, 2017 1:46:23 PM > > > >> Subject: [weld-dev] How to make method injection when bean subclass is > > > >> required in Weld? > > > >> > > > >> Hi all, > > > >> > > > >> I am really sorry for writing to this mailing list, but I checked all > > > >> user > > > >> forums and chats and saw that they are very old. > > > >> > > > >> I would be very thankful if someone gives suggestion for solving the > > > >> following problem. > > > >> I have a child and parent class. Child has SimpleFoo, Parent needs > > > >> Advaced > > > >> foo. So, > > > >> > > > >> @Dependent > > > >> public class SimpleFoo { > > > >> } > > > >> > > > >> @Dependent > > > >> public class AdvancedFoo extends SimpleFoo { > > > >> } > > > >> > > > >> @Dependent > > > >> public class Child { > > > >> > > > >> private SimpleFoo foo; > > > >> > > > >> @Inject > > > >> protected void setFoo(SimpleFoo foo) { > > > >> this.foo = foo; > > > >> } > > > >> } > > > >> > > > >> @Dependent > > > >> public class Parent extends Child { > > > >> > > > >> @Inject > > > >> @Override > > > >> protected void setFoo(SimpleFoo foo) { //How to inject here > > > >> AdvancedFoo? > > > >> super.setFoo(foo); > > > >> } > > > >> } > > > >> > > > >> How to inject in Parent AdvancedFoo? I know that I can do it via > > > >> constructor > > > >> injection > > > >> but I need method injection. How to do it? Can it be done without > > > >> using > > > >> names > > > >> (like MyBean1) > > > >> but only using classes (AdvancedFoo)? > > > >> > > > >> Best regards, Alex > > > >> > > > >> > > > >> > > > >> > > > >> > > > >> -- > > > >> Alex Sviridov > > > >> > > > >> _______________________________________________ > > > >> weld-dev mailing list > > > >> [email protected] > > > >> https://lists.jboss.org/mailman/listinfo/weld-dev > > > > _______________________________________________ > > > > weld-dev mailing list > > > > [email protected] > > > > https://lists.jboss.org/mailman/listinfo/weld-dev > > > > > > > > > > -- > > > Martin Kouba > > > Senior Software Engineer > > > Red Hat, Czech Republic > > > > > > > > > _______________________________________________ > > > weld-dev mailing list > > > [email protected] > > > https://lists.jboss.org/mailman/listinfo/weld-dev > > > > > > _______________________________________________ > > weld-dev mailing list > > [email protected] > > https://lists.jboss.org/mailman/listinfo/weld-dev > > > _______________________________________________ > weld-dev mailing list > [email protected] > https://lists.jboss.org/mailman/listinfo/weld-dev _______________________________________________ weld-dev mailing list [email protected] https://lists.jboss.org/mailman/listinfo/weld-dev
