Tangresh
Tangresh

Reputation: 176

How to create a default binding for a generic interface to a generic implementation with GIN?

I am trying Google GIN for our project and I came across a case where I have a generic interface and a generic implementation of that interface:

public interface IFace<T> {
    void setEntry(T t);
}

public class Face<T> implements IFace<T> {
    public void setEntry(T t) {
    }
}

Now I have a user of the interface that needs an IFace injected in the constructor:

public class IFaceUser {
    private IFace<String> face;

    @Inject
    public IFaceUser(IFace<String> face) {
        this.face = face;
    }
}

If I try to bind the interface to the implementation with bind(IFace.class).to(Face.class);, the injection fails with

Deferred binding result type 'IFace' should not be abstract

So GIN doesn't find a binding for IFace<String> and falls back to IFace use the binding and tries GWT.create(IFace.class).

I also tried bind(new TypeLiteral<IFace>(){}).to(new TypeLiteral<Face>(){}); and bind(new TypeLiteral<IFace<?>>(){}).to(new TypeLiteral<Face<?>>(){}); with no success.

I know I could bind IFace<String> to Face<String>, but that could lead to a huge Module with lots of repeating code in it. It is also possible to use @ImplementedBy(Face.class), but that is not an option.

Is there a magic bind(...).to(...) combination I need to use? Is this even possible with GIN?

Upvotes: 1

Views: 1155

Answers (1)

Tangresh
Tangresh

Reputation: 176

It seems this is not possible with GIN.

There are several workarounds:

  • Let GIN inject an IFace or IFace and then cast to the desired type
  • Write a factory for IFace with a Provider injected that performs the cast in a generic factory method. Inject that factory and get a typesafe instance of IFace from the factory.

Upvotes: 1

Related Questions