Steve Kallestad
Steve Kallestad

Reputation: 3573

Using Guice with a custom class?

I'm working with a Guice enabled framework.

When using classes that were created by the framework (or subclasses that override existing bindings), I can instantiate framework provided variables very easily. Whatever I need, it's just a matter of

@Inject
FrameworkProvidedType variable;

However, in my custom created classes, that doesn't work. All of the injected variables are null.

It's my understanding that in order to use injection, my class has to have a binding.

If I'm subclassing an existing framework class, I can override the binding in my module class. That's pretty straightforward.

But I have a new class and I don't know how to bind it to the underlying framework.

public Class myCustomClass {

   private String iNeedthis;
   private Context thisToo;

   @Inject
   FrameWorkThing magic;

   public myCustomClass(String iNeedThis, Context thisToo){
         this.iNeedThis = iNeedThis;
         this.thisToo = thisToo;
   }

   public void DoMagic(){
        //null pointer error because magic was not injected
        magic.doMagic(this.iNeedthis);
   }
}

How do I Guice-enable this new class?

I tried this in my Runtime Module

public Class<myCustomClass> bindMyCustomClass(){
    return MyCustomClass.class;
}

and failed miserably.

Upvotes: 2

Views: 259

Answers (1)

Steve Kallestad
Steve Kallestad

Reputation: 3573

No thanks to @bmorris591 who dismissed and downvoted the question out of the gate, I found an answer.

@Inject-ing a field into a class means that the class instance needs to be created by Guice.

Step 1 is creating a factory for the class. This may not be necessary, but it worked for me.

public interface MyCustomClassFactory {
    public MyCustomClass create(String iNeedThis, Context thisToo);
}

Step 2 is installing the factory into Guice

@Override
public void configure(Binder binder) {

    super.configure(binder);

    binder.install(new FactoryModuleBuilder().build(MyCustomClass.class));
}

In my particular case - the framework I'm working with provides a Module class that is an implementation of com.google.inject.Module.

Within that class is a "configure(Binder binder)" function that is called on startup.

Step 3 is actually annotating the constructor

@Inject
public myCustomClass(String iNeedThis, Context thisToo){
     this.iNeedThis = iNeedThis;
     this.thisToo = thisToo;
}

Useful and related web page that put me on the right track:

http://beust.com/weblog/2012/08/21/advanced-dependency-injection-with-guice/

This talks about assisted injection, but it gave enough information and a simple enough to understand example that taking the next step was pretty easy.

Upvotes: 1

Related Questions