Search code examples
javadependency-injectionguice

Guice implicitly assigns a value to AssistedInject variable


When I run the code below, I get the output "Bar got 1234". it looks like Guice can't find a binding for num2, and implicitly assigns the value of num1. Is this part of the AssistedInject feature? I couldn't find any mention of this in the wiki. Changing num2's type to float throws this exception (as I'd expected): "No implementation for java.lang.Float annotated with @com.google.inject.assistedinject.Assisted(value=) was bound."

class Foo {
  @Inject
  public Foo(@Assisted final int num1, final Bar bar) {}

  interface FooFactory {
    Foo create(final int num1);
  }
}

class Bar {
  @Inject
  public Bar(@Assisted final int num2) {
    System.out.println("Bar got " + num2);
  }
}

class BillingModule extends AbstractModule {
  @Override
  protected void configure() {
    install(new FactoryModuleBuilder().implement(Foo.class, Foo.class).build(Foo.FooFactory.class));
  }
}

public class App {
  public static void main(String[] args) {
    Injector injector = Guice.createInjector(new BillingModule());
    Foo.FooFactory fooFactory = injector.getInstance(Foo.FooFactory.class);
    fooFactory.create(1234);
  }
}

Solution

  • If you look at the Assisted implementation, you will find that it is a binding annotation.

    @BindingAnnotation
    @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Assisted {
      String value() default "";
    }
    

    Every parameter of the same type marked with binding annotation (@Assisted in your case) will have the same value.