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.

Reply via email to