Reputation: 1
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
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.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
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
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