kohlhaas / google-gin

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

Installed modules are reconstructed for each provider method invocation #134

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
This can lead to different behavior than that expected from Guice, or even 
total failure if the module doesn't have a zero-arg constructor.  

For instance this always provides 5 as the integer value, while in Guice it 
would return an incrementing number:

public class MyModule extends AbstractModule {

  private int foo = 5;

  protected void configure() {
  }

  @Provides
  public int provideFoo() {
    return ++foo;
  }
}

A more likely pattern that will suffer the same problem is likely to arise once 
Gin supports PrivateModules (I'm working on it) is the "solution" to the Robot 
Legs Problem:
http://code.google.com/p/google-guice/wiki/FrequentlyAskedQuestions#How_do_I_bui
ld_two_similar_but_slightly_different_trees_of_objec

Specifically, the module *cannot* be constructed without passing values in, and 
it is necessary to pass the argument into the module in order prevent conflict 
from having the same module installed twice.

Original issue reported on code.google.com by bchamb...@google.com on 17 Jan 2011 at 11:27

GoogleCodeExporter commented 9 years ago
Looks like an actual problem I agree. Gin should probably instantiate each 
module at most once and re-use the instance. I'll work on it.

Original comment by aragos on 21 Jan 2011 at 9:20

GoogleCodeExporter commented 9 years ago
Cool.  I've thought some more about this, and it seems like there are two parts 
to this issue, one which is "easy" to solve and one which is much harder.  For 
the "easy" part, instantiating each module at most once would be the perferct 
solution, and it would handle the example above the incrementing number.  

The harder case is where the only constructor for the module expects arguments 
that are passed to the "install" call.  For instance:
  install(new BadGinModule(5005));
Handling that would require recording the arguments that the module was 
instantiated with, and copying it into the GinjectorImpl.  Not sure if that one 
is as feasible.

Original comment by bchamb...@google.com on 21 Jan 2011 at 9:40

GoogleCodeExporter commented 9 years ago
Good point. I think there is a solution though:

The only way to instantiate a module with parameters is in an install() call 
inside Gin modules. Since we proxy all install calls (before forwarding them to 
Guice) we can easily keep track of module instances created there and use them 
later. 

Original comment by aragos on 21 Jan 2011 at 10:00

GoogleCodeExporter commented 9 years ago
I think that will solve a large chunk of these problems, especially if we can 
remember the actual arguments to that call.  It gets harder, though, if they do:
  install(new BadModule(new Random().getInt())
or something like that.  Not sure that that kind of extreme is worth 
supporting...

Original comment by bchamb...@google.com on 21 Jan 2011 at 10:55