Injecting objects with constructor parameters?

7,270 views
Skip to first unread message

motes

unread,
Jan 14, 2010, 4:56:55 PM1/14/10
to google-guice
I have this simple class:


public class Ford implements Automobile {
private int maxSpeed;

public Ford(int speed) {
System.out.println("Driving a Ford!");
this.maxSpeed = speed;
}

@Override
public int getMaxSpeed() {
return maxSpeed;
}

public void printBrand(){
System.out.println("Ford");

}
}


I would like to inject this implementation into the CarShop below:


public class CarShop {
private Automobile car;
@Inject
public CarShop(Automobile car) {
this.car = car;
}

public void printBrand(){
car.printBrand();
}

public void printMaxSpeed(){
car.getMaxSpeed();
}
}


In my Module I do:

public class MyCarModule extends AbstractModule {
@Override
protected void configure() {
bind(Automobile.class).to(Ford.class);
}
}


But how do I get the int passed to the constructor in my Ford
implementation?

I have looked at:

http://code.google.com/docreader/#p=google-guice&s=google-guice&t=FrequentlyAskedQuestions


but it seems pretty overkill to create a factory or an AssistedInject
to pass an int to a constructor.

Any ideas?

Fred Faber

unread,
Jan 14, 2010, 5:37:11 PM1/14/10
to google...@googlegroups.com
Where is the value of the int coming from?

If it's known at configure() time, then simply bind it:

bind(int.class).toInstance(60);

most likely you'll need to annotate it:

class Ford implements Automobile {

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.PARAMETER)
    @BindingAnnotation
    @interface  ForFord { }

     @Inject
     Ford(@ForFor int maxSpeed) {
       ...
     }
  }

at which point you can use the type converters in guice to do:

bindConstant().annotatedWith(ForFord.class).to(65);

-Fred
--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To post to this group, send email to google...@googlegroups.com.
To unsubscribe from this group, send email to google-guice...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.




motes

unread,
Jan 15, 2010, 3:42:05 AM1/15/10
to google-guice
My plan was to let the user specify the int at runtime and then pass
it to the module like:


public class Test {

public static void main(String[] args) {
// Get userinput. Path to xml frame.
int userInt = Integer.parseInt(args[0]);
Injector injector = Guice.createInjector(new MyCarModule
(userInt));
CarShop carShop = injector.getInstance(CarShop.class);
}
}

Then in the module I can do:

public class MyCarModule extends AbstractModule {

private int tt;
public MyCarModule(int tt) {
this.tt = tt;
}

@Override
protected void configure() {

bind(Automobile.class).to(Ford.class);
bind(String.class).annotatedWith(Names.named
("LicenseKey")).toInstance(tt);

But is it this how guice is intented to be used (passing external
resources to the module constructor)?


On Jan 14, 11:37 pm, Fred Faber <ffa...@gmail.com> wrote:
> Where is the value of the int coming from?
>
> If it's known at configure() time, then simply bind it:
>
> bind(int.class).toInstance(60);
>
> most likely you'll need to annotate it:
>
> class Ford implements Automobile {
>
>     @Retention(RetentionPolicy.RUNTIME)
>     @Target(ElementType.PARAMETER)
>     @BindingAnnotation
>     @interface  ForFord { }
>
>      @Inject
>      Ford(@ForFor int maxSpeed) {
>        ...
>      }
>   }
>
> at which point you can use the type converters in guice to do:
>
> bindConstant().annotatedWith(ForFord.class).to(65);
>
> -Fred
>

> >http://code.google.com/docreader/#p=google-guice&s=google-guice&t=Fre...


>
> > but it seems pretty overkill to create a factory or an AssistedInject
> > to pass an int to a constructor.
>
> > Any ideas?
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "google-guice" group.
> > To post to this group, send email to google...@googlegroups.com.
> > To unsubscribe from this group, send email to

> > google-guice...@googlegroups.com<google-guice%2Bunsu...@googlegroups.com>

Gary Pampara

unread,
Jan 15, 2010, 3:52:45 AM1/15/10
to google...@googlegroups.com
This is possible but Guice by default cannot do that, unless the
integer is named, as Fred described.

You could possibly do one of the following:
- Using a builder to create the instance for you (there are some
examples on the list that I cannot seem to locate now)
- You could consider using the AssistedInject extension
(http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/assistedinject/FactoryProvider.html)

- Gary

> To unsubscribe from this group, send email to google-guice...@googlegroups.com.

motes

unread,
Jan 15, 2010, 4:27:32 AM1/15/10
to google-guice
Maybe I misunderstand but simply passing arguments to the MyCarModule
constructor and then using the values in the bindings works fine:


public class Test {

public static void main(String[] args) {
// Get userinput. Path to xml frame.
int userInt = Integer.parseInt(args[0]);
Injector injector = Guice.createInjector(new MyCarModule
(userInt));

...

}


public class MyCarModule extends AbstractModule {
private int tt;
public MyCarModule(int tt) {
this.tt = tt;

System.out.println(tt);
}

prints 42 when this is passed as userinput.

next 'tt' can be used in

bind(String.class).annotatedWith(Names.named
("LicenseKey")).toInstance(tt);

But instead of passing resources in the Module constructor an
alternative is to call a "readInput()" method from the "configure()"
method in the module:

@Override
protected void configure() {
readUserInput();
}

private void readUserInput() {
// read the input using eg. swing.
}


This is how I currently solve the userinput problem.

On Jan 15, 9:52 am, Gary Pampara <gpamp...@gmail.com> wrote:
> This is possible but Guice by default cannot do that, unless the
> integer is named, as Fred described.
>
> You could possibly do one of the following:
>  - Using a builder to create the instance for you (there are some
> examples on the list that I cannot seem to locate now)
>  - You could consider using the AssistedInject extension

> (http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/injec...)
>
> - Gary

Asier

unread,
Jan 15, 2010, 6:01:17 AM1/15/10
to google...@googlegroups.com
El 15/01/2010 9:42, motes escribi�:

> My plan was to let the user specify the int at runtime and then pass
> it to the module like:
>
>
> public class Test {
>
> public static void main(String[] args) {
> // Get userinput. Path to xml frame.
> int userInt = Integer.parseInt(args[0]);
> Injector injector = Guice.createInjector(new MyCarModule
> (userInt));
> CarShop carShop = injector.getInstance(CarShop.class);
> }
> }

Perhaps an Assisted Injection is what you are looking for?

http://code.google.com/p/google-guice/wiki/AssistedInject

http://stackoverflow.com/questions/996300/how-to-use-google-guice-to-create-objects-that-require-parameters

Thanks

Alen Vrečko

unread,
Jan 15, 2010, 2:23:41 PM1/15/10
to google-guice
Reply all
Reply to author
Forward
0 new messages