frjaeger220 / google-guice

Automatically exported from code.google.com/p/google-guice
Apache License 2.0
0 stars 0 forks source link

AssistedInject: Multi-type factories #346

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Assisted inject currently allows only such factory interfaces to be used
whose methods all return exactly one type.  In addition, that type can be
specified when initializing the factory
(FactoryProvider.newFactory(MyFactory.class, MyType.class)).  

From my experience, it would reduce boilerplate code greatly if (a) the
return type for a factory method could be inferred from its actual return
type, and (b) a factory interface can contain multiple methods that return
different types.

This is a proposal for a new factory provider that allows creation of
factories that fulfill both of the above definitions and still remains
flexible.  I dubbed these factories multi-type factories, and the
proxy-generator a MultiFactoryProvider.  A very early draft (neither fully
tested nor implemented, but illustrating some of the idea) can be found at:
 http://codereview.appspot.com/25084/show.  I'll update the draft as I add
more features/tests.

bind(MyFactory.class).toProvider(MultiFactoryProvider.newFactory(MyFactory.class
));

Note that the draft currently does not contain the ability to specify
bindings for return types in module configurations, which would (probably)
look like this:

FactoryBinder factoryBinder = new FactoryBinder();
// Causes "Animal getAnimal(String name);" to use Dog(@Assisted String
name) constructor.
factoryBinder.bind(Animal.class).to(Dog.class);

// Causes "@Furry Animal getAnimal(String name);" to use Dog(@Assisted
String name) constructor.
factoryBinder.bind(Animal.class).annotatedWith(Furry.class).to(Cat.class);

bind(MyFactory.class).toProvider(MultiFactoryProvider.newFactory(AnimalFactory.c
lass,
factoryBinder));

= or =

bind(MyFactory.class).toProvider(MultiFactoryProvider.newFactory(AnimalFactory.c
lass,
new FactoryBinder(Animal.class, Furry.class, Cat.class)));

Please let me know what you think!

Original issue reported on code.google.com by aragos on 10 Mar 2009 at 10:25

GoogleCodeExporter commented 9 years ago
there was a patch awhile back that revised the internals of assistedinject to 
support
this usecase, but that part of it was stripped out i believe.

fwiw, i'm very much in favor of re-adding it.

Original comment by sberlin on 10 Mar 2009 at 10:37

GoogleCodeExporter commented 9 years ago
I updated the code review:  The new functionality was merged into 
FactoryProvider2
(tiny changes really), it is backwards compatible (i.e. all tests pass as 
before) and
provides a configuration language that should provide a super-set of the current
functionality.  The new code also contains full documentation for the new 
functionality.

Pleas review and let me know what you think!

Original comment by aragos on 12 Mar 2009 at 1:15

GoogleCodeExporter commented 9 years ago
Looking at the code, I don't see a multi-binding improvement, yet.  The 
signature of
FactoryProvider2 still takes a single type.  It seems we would still need a lot 
of
boilerplate code to inject the following factory:

public interface AnimalFactory{
   Dog createDog(Color color);
   Cat createCat(Color color);
}

Am I missing something?

Original comment by fernc...@gmail.com on 15 Apr 2009 at 1:39

GoogleCodeExporter commented 9 years ago
After some discussion, we changed the configuration interface to use a module 
which
you can install:

configure() {
  install(new FactoryModuleBuilder()
      .implement(Animal.class, Dog.class)
      .implement(Animal.class, Names.named("cat"), Cat.class)
      .build(AnimalFactory.class));
}

or, if you have implementation types returned in your factory as in your 
example:

install(new FactoryModuleBuilder().build(AnimalFactory.class));

Take a look at the FactoryModuleBuilder in the code review (latest patch set) 
to see
all configuration options.

Original comment by aragos on 15 Apr 2009 at 4:18

GoogleCodeExporter commented 9 years ago
Looks exactly what I need.  I'm not comfortable having a patch dependency, so 
I'll
code-comment that the ugly boilerplate code will go away when this is 
implemented.

Thanks!
-Adrian 

Original comment by fernc...@gmail.com on 15 Apr 2009 at 4:34

GoogleCodeExporter commented 9 years ago

Original comment by limpbizkit on 26 Apr 2009 at 9:05

GoogleCodeExporter commented 9 years ago
This has been committed a few weeks ago, I believe.

Original comment by aragos on 23 Sep 2009 at 8:33

GoogleCodeExporter commented 9 years ago
this was fixed a long time back.

Original comment by sberlin on 3 Apr 2010 at 10:56

GoogleCodeExporter commented 9 years ago
Since it was fixed, is it possible to document it somehow in the wiki or by
generating the Javadoc?

Original comment by ogregoire on 4 Apr 2010 at 12:02

GoogleCodeExporter commented 9 years ago
The 2.0 release doesn't contain the fix I think (based on a very quick glance 
at the
sources of the 2.0 release on the download page).  If you compile Guice &
AssistedInject from the latest svn revision, take a look at the javadoc for
FactoryModuleBuilder.

Original comment by sberlin on 4 Apr 2010 at 1:56