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.

Reply via email to