xiaodududu / google-guice

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

Provider Factory and then Inject what the Provider returns #655

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I think this is partly related to Issue #131, FactoryModuleBuilder & Co but 
with a slightly different twist. I'm not interested in the Factories themselves 
(which seems to be the purpose of FactoryModuleBuilder and FactoryProvider) but 
would rather tell Guice how to create Objects for me with some arguments that I 
provide and with some arguments that Guice can inject for me.

Here is an example where I provide the type of my POJO, Guice injects some 
additional stuff to my factory method and I do something with it (e.g. use the 
arguments to read some resource such as JSON/XML and create a POJO from that).

public class ConfigModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(PicasaConfig.class).toFactory(new ConfigFactory<PicasaConfig>(PicasaConfig.class));
    bind(FlickrConfig.class).toFactory(new ConfigFactory<FlickrConfig>(FlickrConfig.class));
  }
}

public class ConfigFactory<T> {

  private final Class<T> type;

  public ConfigFactory(Class<T> type) {
    this.type = type;
  }

  @Provides @Inject
  public T create(@Named("mv.config.cl") ClassLoader loader, @Named("my.env") String environment) {
    return DoSomeMagic.newInstance(loader, environment, type);
  }
}

@Singleton
public class PicasaProcessor {

  private final PicasaConfig config;

  @Inject
  public PicasaProcessor(PicasaConfig config) {
    this.config = config;
  }
}

Original issue reported on code.google.com by rka...@gmail.com on 26 Sep 2011 at 7:09

GoogleCodeExporter commented 9 years ago
I think Fred made an extension that does something like what you're looking for 
(LegsProvider?), cc'ing him.

Original comment by sberlin on 26 Sep 2011 at 7:22

GoogleCodeExporter commented 9 years ago
It looks like I can do something like this... 

public class ConfigModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(PicasaConfig.class).toProvider(new ConfigProvider<PicasaConfig>(PicasaConfig.class));
    bind(FlickrConfig.class).toProvider(new ConfigProvider<FlickrConfig>(FlickrConfig.class));
  }
}

public class ConfigProvider<T> implements Provider<T> {

  private final Class<T> type;

  private volatile ClassLoader loader;

  private volatile Environment environment;

  public SettingsProvider(Class<T> type) {
    this.type = type;
  }

  @Inject
  void init(@Named("mv.config.cl") ClassLoader loader, @Named("my.env") String environment) {
    this.loader = loader;
    this.environment = environment;
  }

  @Override
  public T get() {
    return DoSomeMagic.newInstance(loader, environment, type);
  }
}

Original comment by rka...@gmail.com on 26 Sep 2011 at 9:04