Thanks for the summary, that's very good. I'll stay with FactoryModuleBuilder and see how it goes...
-Dave On Tue, Apr 12, 2011 at 5:08 PM, Sam Berlin <[email protected]> wrote: > Yup, AssistedInject in Guice 3.0 requires a little more coordination > between the implementation & the factory, especially when more than one > parameter is of the same type. The benefits are large, though: > > From the Guice 3.0 Wiki, these are the changes since 2.0: > > * New FactoryModuleBuilder for building assisted factories > * Injection is done through child injectors and can participate in AOP > * Performance improvements > * Multiple different implementations can be created from a single factory > * Incorrect implementations or factories are detected in Stage.TOOL, and > more error-checking with better error messages > * Work better with parameterized types > * Expose details through new extensions SPI > > I don't think any of those are applicable if you continue to use > FactoryProvider and leave the implementation annotated with > @AssistedInject. (However, if you change the implementation to @Inject, > you'll see the new behavior regardless of whether or not you use > FactoryProvider of FactoryModuleBuilder. Also, if you use > FactoryModuleBuilder, you'll always get the new behavior regardless of using > @Inject or @AssistedInject). > > Long story short... you're really better off using FactoryModuleBuilder. > > sam > > > On Tue, Apr 12, 2011 at 8:53 AM, dhoffer <[email protected]> wrote: > >> I had got it working with I guess it's the 2.0 way of doing >> things...with this style binding: >> >> bind(IMyClassFactory.class).toProvider( >> FactoryProvider.newFactory(IMyClassFactory.class, >> MyClass.class)); >> >> but FactoryProvider is deprecated. >> >> So now that I see your post saying that I need to used 'named' >> annotations I changed it to use this approach. >> >> install(new FactoryModuleBuilder() >> .implement(IMyClass.class, MyClass.class) >> .build(IMyClassFactory.class)); >> >> however with this approach I have to used named Assisted annotations >> in MyClass and I have to add named Assisted annotations to >> IMyClassFactory where none was needed with the 2.0 approach. (Seems >> like order of parameters could be used.) >> >> Both seem to work but the 2.0 approach as less intrusive to the code >> (interfaces). ...just my two-cents. >> >> Thanks much! >> -Dave >> >> On Apr 12, 3:08 pm, Fred Faber <[email protected]> wrote: >> > On Tue, Apr 12, 2011 at 2:28 AM, dhoffer <[email protected]> wrote: >> > > Yeah, that's what I was missing. This should do exactly what I need >> > > but I can't get it to work yet. It compiles but at runtime it fails. >> > > I find the documentation on this feature too sparse. Instead of >> > > giving one full example they jump between two separate partial >> > > examples. >> > >> > > In particular the docs don't make clear which module it is referring >> > > to. In my case the class to be dynamically created has no non- >> > > assisted parameters. I.e. the constructor of that class has 5 >> > > parameters and they all have the @Assisted annotation. >> > >> > > So then question 1 is...should this class have the @Inject annotation >> > > or the @AssistededInject annotation? >> > >> > It should use @Inject....@AssistedInject was used in the initial >> version of >> > the library, which uses reflection and not a child injector to create >> the >> > factory-created objects. >> > >> > > The docs aren't real clear on >> > > this, I think the later is needed only if I have overloaded >> > > constructors which I do not. Question 2 is...do I even need a module >> > > for this class? Since it has no injected parameters it seems it has >> > > nothing to do. >> > >> > You'll need to bind the Factory as you show below (I'm unclear what >> "class" >> > you mean in this question). You won't bind the class being created by >> the >> > factory, if that's the question. >> > >> > >> > >> > > Now for the class(s) that need to inject the factory interface I >> > > assume these are the modules that need this: >> > > install(new FactoryModuleBuilder() >> > > .implement(IMyClass.class, MyClass.class) >> > > .build(IMyClassFactory.class)); >> > >> > > And this would be positioned in the module to line up with the >> > > IMyClassFactory injected parameter (which in my case is after the bind >> > > methods). >> > >> > Ok. >> > >> > >> > >> > >> > >> > > However at runtime I get this error: >> > >> > > com.google.inject.CreationException: Guice creation errors: >> > >> > > 1) A binding to com.app.MyParam annotated with >> > > @com.google.inject.assistedinject.Assisted(value=) was already >> > > configured at com.app.IMyClassFactory.create(). >> > > at com.app.IMyClassFactory.create(IMyClassFactory.java:1) >> > > at >> > >> > > >> com.google.inject.assistedinject.FactoryProvider2.initialize(FactoryProvider2.java: >> > > 539) >> > > at com.google.inject.assistedinject.FactoryModuleBuilder >> > > $1.configure(FactoryModuleBuilder.java:335) >> > >> > > Where MyParam is one of the 5 parameters in the IMyClassFactory create >> > > method (i.e. MyClass constructor). >> > >> > I am guessing that more than one parameter has type "MyParam." >> > >> > If this is the case, then you need to distinguish param of the same type >> by >> > "naming" them, e.g., >> > >> > @Inject ClassCreatedByFactory( >> > @Assisted("usedAsUsername") String username, >> > @Assisted("usedAsPassword") String password) { ... } >> > >> > >> > >> > > Any idea what is wrong? Is there a full example of this someplace? >> > >> > Generally there are some examples in the test classes, such as here: >> > >> > http://code.google.com/p/google-guice/source/browse/trunk/extensions/. >> .. >> > >> > Fred >> > >> > >> > >> > > -Dave >> > >> > > On Apr 11, 6:17 pm, Sam Berlin <[email protected]> wrote: >> > > > Take a look at the AssistedInject extension @ >> > >http://code.google.com/p/google-guice/wiki/AssistedInject. >> > >> > > > sam >> > >> > > > On Mon, Apr 11, 2011 at 11:07 AM, David Hoffer <[email protected]> >> > > wrote: >> > > > > Nope, my factories are as plain as they get, i.e. >> > >> > > > > public class MyClassFactory implements IMyClassFactory { >> > >> > > > > public MyClass createMyClass(String param1, String param2, >> String >> > > > > param3, int param4, double param5) { >> > > > > return new MyClass(param1, param2, param3, param4, >> param5); >> > > > > } >> > > > > } >> > >> > > > > The whole purpose of this factory is so I can inject >> IMyClassFactory >> > > into >> > > > > other classes that need to 'new' MyClass so that class is mock >> > > testable. >> > >> > > > > I'd love to use Guice so I don't need to write these factories but >> how >> > > do I >> > > > > pass param1, param2, param3, param4 & param5 into MyClass's >> > > constructor? >> > >> > > > > -Dave >> > >> > > > > On Mon, Apr 11, 2011 at 6:00 PM, Fred Faber <[email protected]> >> wrote: >> > >> > > > >> This is similar to a question from earlier this week... >> > >> > > > >> Guice will help you remove invocations of "new" on service >> objects. >> > >> > > > >> It won't be a replacement for your domain-level factory objects >> i.e., >> > > > >> objects that do more work on an object than simply instantiate >> it. >> > >> > > > >> Such a factory might look like: >> > >> > > > >> class YourFactory { >> > > > >> private final Provider<Foo> fooProvider; >> > >> > > > >> @Inject YourFactory(Provider<Foo> fooProvider) { >> > > > >> ... >> > > > >> } >> > >> > > > >> Foo createFoo(ArgType1 arg1, ArgType2 arg2, ...) { >> > > > >> Foo foo = fooProvider.get(); >> > > > >> ... manipulate foo, probably using the args given above >> > > > >> } >> > > > >> } >> > >> > > > >> Note that AssistedInject can remove the boilerplate if all the >> factory >> > > is >> > > > >> doing is to use the argument it gets as constructor arguments to >> the >> > > thing >> > > > >> it is creating. But it sounds like your requirements are more >> > > in-depth in >> > > > >> that the Factory seems to be doing more work than simply >> instantiating >> > > an >> > > > >> object. >> > >> > > > >> Fred >> > >> > > > >> On Mon, Apr 11, 2011 at 10:45 AM, dhoffer <[email protected]> >> wrote: >> > >> > > > >>> I'm taking a look at Guice to see how it would work for us, >> currently >> > > > >>> we code the IoC manually (giant main that wires everything up) >> and >> > > use >> > > > >>> factories to create dynamic objects so all methods are mock >> testable, >> > > > >>> i.e. no 'new' in the code (just in the main and factories). >> > >> > > > >>> I get how Guice solves the IoC part with @Inject & modules, >> however >> > > > >>> how does it help with the factories that generate dynamic >> objects? >> > > > >>> I.e. a method that calculates values, creates an object with >> those >> > > > >>> values, and does some work on and/or returns the object. How >> does >> > > > >>> Guice stop us from needing to write the class factory that >> generates >> > > > >>> the object? It looks like I could inject a typed Provider but >> that >> > > > >>> doesn't let me create the object with the values just created >> > > > >>> dynamically. (Also it would tie my code to the Guice APIs.) >> > >> > > > >>> So it seems Guice solves the static part of the app but not the >> > > > >>> dynamic part or am I missing something? >> > >> > > > >>> -- >> > > > >>> You received this message because you are subscribed to the >> Google >> > > Groups >> > > > >>> "google-guice" group. >> > > > >>> To post to this group, send email to >> [email protected]. >> > > > >>> To unsubscribe from this group, send email to >> > > > >>> [email protected]. >> > > > >>> For more options, visit this group at >> > > > >>>http://groups.google.com/group/google-guice?hl=en. >> > >> > > > > -- >> > > > > You received this message because you are subscribed to the Google >> > > Groups >> > > > > "google-guice" group. >> > > > > To post to this group, send email to >> [email protected]. >> > > > > To unsubscribe from this group, send email to >> > > > > [email protected]. >> > > > > For more options, visit this group at >> > > > >http://groups.google.com/group/google-guice?hl=en. >> > >> > > -- >> > > You received this message because you are subscribed to the Google >> Groups >> > > "google-guice" group. >> > > To post to this group, send email to [email protected]. >> > > To unsubscribe from this group, send email to >> > > [email protected]. >> > > For more options, visit this group at >> > >http://groups.google.com/group/google-guice?hl=en. >> >> -- >> You received this message because you are subscribed to the Google Groups >> "google-guice" group. >> To post to this group, send email to [email protected]. >> To unsubscribe from this group, send email to >> [email protected]. >> For more options, visit this group at >> http://groups.google.com/group/google-guice?hl=en. >> >> > -- > You received this message because you are subscribed to the Google Groups > "google-guice" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/google-guice?hl=en. > -- You received this message because you are subscribed to the Google Groups "google-guice" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.
