Hi Martin Thank you very much for your comment and suggestion about improving.
Best regards, Alex >Четверг, 31 августа 2017, 12:50 +03:00 от Martin Kouba <[email protected]>: > >Hi Alex, > >1) should work but looks a little bit cumbersome. WRT 2) you should >avoid using BeanManager to create a bean instance whenever possible. And >in this particular case, if SimpleFoo is @Dependent it wouldn't be >destroyed correctly (@PreDestroy) when Parent or Child is destroyed. > >The following should also work (no need to have two Instance IPs): > >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 { > > @Override > protected AdvancedFoo newFoo() { > return fooInstance.select(AdvancedFoo.class).get(); > } > } > > >Martin > >Dne 31.8.2017 v 11:07 Alex Sviridov napsal(a): >> Hi Martin, >> >> >> Could you comment the following solutions? >> >> 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; >> } >> } >> >> >> Best regards, Alex >> >> Среда, 30 августа 2017, 10:51 +03:00 от Matej Novotny >> < [email protected] <mailto: [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] >> <mailto: [email protected] >> >> > To: "weld-dev" < [email protected] >> <mailto: [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] <mailto: [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] >> <mailto: [email protected] > > >> > >> To: "weld-dev" < [email protected] >> <mailto: [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] <mailto: [email protected] > >> > >> https://lists.jboss.org/mailman/listinfo/weld-dev >> > > _______________________________________________ >> > > weld-dev mailing list >> > > [email protected] <mailto: [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] <mailto: [email protected] > >> > https://lists.jboss.org/mailman/listinfo/weld-dev >> >> >> >> ------------------------------------------------------------------------ >> >> -- >> Alex Sviridov > >-- >Martin Kouba >Senior Software Engineer >Red Hat, Czech Republic -- Alex Sviridov
_______________________________________________ weld-dev mailing list [email protected] https://lists.jboss.org/mailman/listinfo/weld-dev
