2

I have three Modules in Guice:

  • ReflectionsModule, for providing Metadata (via Reflections)
  • PersistenceModule, for Data Access Objects and Others
  • WebModule, for Web Stuff

Simply put, both PersistenceModule and WebModule will fetch a object which is made from Reflections Module. I can not find a very friendly way to do this in guice.

I think PrivateModules will be a suitable way around, but I am not sure how to implement that. Any ideas?

Thank you.

Some additional details

I am using Reflections. It is basically a wrapper to load persistence metadata from a static resource. So basically supposed a parsed XML file into a JavaBean. Thats the concern of the ReflectionsModule.

From this metadata into the javabean, I need to setup the persistence (its a Google App Engine App, using Objectify) and load additional classes and bind them while reading some annotations within. I do not want to load the resource, so I'd like to refer to the resource loaded from the first example.

For now, the ReflectionsModule also binds the two subsequent modules, which I get (correctly) and apply them to the createChildInjector which came when building with just the first module. As os now, it works. I just would like to know which way would be the best one.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
aldrinleal
  • 3,559
  • 26
  • 33
  • What is your problem, concretely? I see no particular problem in what you describe. Maybe some snippet of what you are doing (or trying to do) would help. – jfpoilpret Jun 20 '10 at 11:45

2 Answers2

2

EDIT: better answer found: https://stackoverflow.com/a/5504903/105741 - basically use @Provides annotation to get method parameters in your module injected with your dependencies from other modules. Works much nicer. I.e. for the binding that requires the DependencyClass, I move that code into a method, expose it with the @Provides annotation, and add the DependencyClass as a method parameter.

@dyross - I don't think that's what he's asking.

It's not a good idea to create the ReflectionModule more than once, and PrivateModules don't have anything to do with the problem - that of sharing bindings to children modules (if I understand him correctly). I have the same need, and have used the technique of passing in the required object to the children modules ie.

Injector parentInjector = Guice.createInjector(new ParentModule());
DependencyClass dep = parentInjector.getInstance(DependencyClass);
injector = parentInjector.createChildInjector(new ChildModule(dep));

i.e.

Injector reflectionsModule = Guice.createInjector(new ReflectionsModule());
DependencyClass dep = parentInjector.getInstance(DependencyClass);
injector = parentInjector.createChildInjector(
                              new PersistenceModule(dep), 
                              new WebModule(dep));

Not ideal, but serves the purpose.

It also just occured to me that you could pass in the injector to the child modules too, and getInstance() from directly inside the child modules.

Community
  • 1
  • 1
Antony Stubbs
  • 13,161
  • 5
  • 35
  • 39
2

Simply speaking, PrivateModules expose only bindings that are explicitly exposed using @Exposed annotation of the .expose() method. Therefore, if PersistenceModule and WebModule are both PrivateModules, you can do the following:

public class WebModule extends PrivateModule {
  @Override
  public void configure() {
    install(new ReflectionsModule());
    // do stuff...
    expose(SomeClassFromWebModule.class);
  }
}

public class PersistenceModule extends PrivateModule {
  @Override
  public void configure() {
    install(new ReflectionsModule());
    // do stuff...
    expose(SomeClassFromPersitenceModule.class);
  }
}

In this way, the bindings from ReflectionsModule will not be exposed further than the two PrivateModules and will therefore not run into each other.

It is generally a good practice to only expose classes that can only be provided by one Module.

dyross
  • 741
  • 5
  • 18
  • I don't think that's quite what he's getting at, and I don't think PrivateModules are relevant. See my answer for an alternative... – Antony Stubbs Jul 28 '12 at 16:50