willhains / guicebox

Automatically exported from code.google.com/p/guicebox
2 stars 2 forks source link

GuiceBox is calling all provider get() methods on initialization for some reason #26

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create class Foo

public class Foo {
}

2. Create class FooProvider

import com.google.inject.Provider;

public class FooProvider implements Provider<Foo> {
    @Override
    public Foo get() {
        throw new RuntimeException("GuiceBox is being bad");
    }
}

3. Create class FooModule

import com.google.inject.AbstractModule;

public class FooModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(Foo.class).toProvider(FooProvider.class);
    }
}

4. Create a test

import org.guicebox.GuiceBox;
import org.junit.Test;

import com.google.inject.Guice;
import com.google.inject.Injector;

public class GuiceBoxTest {
    @Test
    public void testGuice() throws Exception {
        Injector injector = Guice.createInjector(new FooModule());
        final GuiceBox guiceBox = injector.getInstance(GuiceBox.class); // Initiates your app
        guiceBox.start(); // starts everything bound by your modules that has @Start
    }
}

What is the expected output? What do you see instead?

Expected output is nothing. What I get is the exception being thrown because 
FooProvider.get() is being called even when nothing needs it.

What version of the product are you using? On what operating system?

Tried 0.3 and dev on Windows 7.

Please provide any additional information below.

Original issue reported on code.google.com by r...@urbancode.com on 9 Aug 2012 at 2:24

GoogleCodeExporter commented 9 years ago
Thank you for the clear, well-written bug report.

This is expected behaviour. GuiceBox needs to instantiate at least one instance 
of each bound class (including those instantiated via Providers) in order to 
search it for @Start, @Stop, and @Kill methods.

This is because Guice does not provide a way (afaik) to get the class of a 
bound class from its binding, and anyway there would be no way to do that in 
the case where a Provider is used.

The intention of GuiceBox (and, I believe, Guice as well) is that these objects 
can be instantiated and thrown away with no consequences. If it is important 
for your application that a class is constructed once, or a Provider's get() 
method is called once, you should use Singleton scope, or build another Scope 
to control instantiation.

That said, I do sympathise with the potential application design dilemmas this 
behaviour could cause for you. It seems we need a way to tell GuiceBox, "there 
are definitely no @Start, etc. methods in here, so don't bother instantiating 
one to find out!" Perhaps a new annotation, @DoNotScan, or similar.

FYI - I've been using GuiceBox in production for over 2 years now, and am in 
the middle of a major redesign that is almost ready to commit. Stay tuned!

Original comment by w...@willhains.com on 11 Aug 2012 at 12:23