user2880807
user2880807

Reputation: 1

How to use Google Guice to inject a dependancy

I've gone through the user guide and everything but yet I still don't understand exactly how to modify existing code to use Google Guice when trying to inject dependencies. So to make it easier I created this simple example and if someone could explain with this simple example I would really appreciate it!

Say I have a

public Class A {

    private int count = 0;

    public A() {
    }

    public int getCount() {

      return count;
    }

    public void setCount(int newCount) {

      this.count = newCount;
    }
}

and another class

public Class B {

    private A objectA;

    public B() {
        objectA = new A();
    }

    public void messWithCount() {
        int tempCount = objectA.getCount();
        objectA.setCount(tempCount+1);
    }
}

So basically my question is: how would I go about using Google Guice to extract creation of objectA in the constructor B() and instead inject it as a dependency in Class B where it would amount to something like

@Inject    
public B() {
}  

and how would I actually inject an instance of A into it?

Upvotes: 0

Views: 981

Answers (3)

user2880879
user2880879

Reputation: 297

You can inject A into B in two ways, actually many ways but with in the context of your question I would say two.

  1. Make sure both A and B class is configured in a Module. Follow condit example code/class that extends AbstractModule.

1.a

class B {
   @Inject
   private A a;

   public B() {
   }
}

1.b

class B {
    private A a;

    @Inject
    public B(A a) {
        this.a = a;
    }

}

These both works fine but 1.b is useful if you want to write test for class B. Where your test will mock A class and creates instance of B. like

class BTest {

    @Test
    public void testSomeMethodOfB() {
       A a = mock(A.class);
       B b = new B(a);
       //run some test on b;
    }

} 

Upvotes: 2

Sirotnikov
Sirotnikov

Reputation: 459

First, B should not be bound to class A but rather use an interface (such as AInterface). The main point of Guice is to bind different implementations of the same interface, without being tied to some class.

So let's assume Class A implements AInterface

interface AInterface {
    public int getCount();
    public void setCount(int newCount);
}

class A implements AInterface {
    private int count   = 0;

    public A() {
        System.out.println("done!");
    }

    @Override
    public int getCount() {
        return count;
    }

    @Override
    public void setCount(int newCount) {
        this.count = newCount;
    }
}

Now you tell it to inject your variable:

class B {
    @Inject
    private AInterface  objectA;

    public B() {}

    public void messWithCount() {
        int tempCount = objectA.getCount();
        objectA.setCount(tempCount + 1);
    }
}

I removed the static modifier, but if you insist in having it static you'd need to bind using requestStaticInjection instead

you tie the implementation A to the interface AInterface in a special class called module:

class SimpleModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(AInterface.class).to(A.class);
    }
}

Now you ask Guice to generate B for you.

public class Temptemp {
    public static void main(String[] args) {
        Injector i = Guice.createInjector(new SimpleModule());
        B b = i.getInstance(B.class);

    }
}

Upvotes: 3

condit
condit

Reputation: 10962

Here's an example based on what you already have:

public class GuiceExample {

  static class A {
    private int count = 0;

    public A() {}

    public int getCount() {
      return count;
    }

    public void setCount(int newCount) {
      this.count = newCount;
    }
  }

  static class B {
    @Inject
    private static A objectA;

    public B() {}

    public void messWithCount() {
      int tempCount = objectA.getCount();
      objectA.setCount(tempCount+1);
    }
  }

  static class Module extends AbstractModule {
    @Override 
    protected void configure() {
      requestStaticInjection(B.class);
    }
  }

  @Test
  public void test() {
    Injector i = Guice.createInjector(new Module());
    B b = i.getInstance(B.class);
    //Do something with b
  }

}

Note, though, that static injection is not preferred. You could make A non static and Guice will still inject the field. The even more "correct" way would be to drop the requestStaticInjection call and add A as construction argument like:

  static class B {
    private A objectA;

    @Inject
    public B(A objectA) {
      this.objectA = objectA;
    }

    ...
  }

Upvotes: 0

Related Questions