pombreda / google-guice

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

Support binding Module in parent modules for installation in child modules #795

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
"1) Binding to core guice framework type is not allowed: Module."

I wrote hm.binkley:service-binder (on Maven Central) with the goal of injecting 
modules for child injectors.  Essentially it a version of ServiceLoader which 
can inject loaded instances including non-default constructors.

They key code is:

// service - Class<T> of type to bind ala ServiceLoader.load()
// implemntations - Entries in META-INF/services for the service
// Fails when T == Module
final Multibinder<T> bindings = newSetBinder(binder, service);
for (final Class<? extends T> implementation : implementations)
    bindings.addBinding().to(implementation); // Fails here

For simple modules without dependencies I can use:

@Override
protected void configure() {
    for (Module module : ServiceLoader.load(Module.class))
        install(module);
}

When I use ServiceBinder to get injected modules (modules with non-default 
constructors):

public static final class ServiceBinderParentModule extends AbstractModule {
    @Override
    protected void configure() {
        ServiceBinder.with(binder()).bind(Module.class); // Fails here
     }
}

public static final class ServiceBinderChildModule extends AbstractModule {
    private final Injector guice;

    @Inject
    public ServiceBinderChildModule(@Nonnull final Injector guice) {
        this.guice = guice;
    }

    @Override
    protected void configure() {
        for (final Module module : guice.getInstance(Key.get(new TypeLiteral<Set<Module>>() {})))
            install(module);
    }
}

Use:

parent = createInjector(new ServiceBinderParentModule()); // Fails here
child = 
parent.createChildInjector(parent.getInstance(ServiceBinderChildModule.class));

I've pushed a public branch with sources and tests demonstrating the problem 
(tests marked @Ignore("Guice cannot bind Module")):

https://github.com/binkley/service-binder/tree/feature/GuiceModules

ENHANCEMENT REQUEST - I'd like to support this idiom.  My goal as to use DI on 
modules.  The dependencies go into the parent module, the child module shows up 
with injected modules nicely installed.

Use case is supporting modules as components.  Developers drop a jar into their 
project; the jar contains modules declared in 
META-INF/services/com.google.inject.Module; their main() includes the two lines 
of code directly above: it all "just works".

Original issue reported on code.google.com by b.k.ox...@gmail.com on 4 Feb 2014 at 11:37

GoogleCodeExporter commented 9 years ago
I tried the easy thing of cloning git 4.0-SNAPSHOT, and commenting out 
Module.class and AbstractModule.class from FORBIDDEN_TYPES in 
AbstractBindingProcessor.  My tests for Guice all pass with that change.

I don't now the reason for the restriction, unsure what havoc this change might 
wreak.

Original comment by b.k.ox...@gmail.com on 5 Feb 2014 at 9:29