Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guice Generic Provider (the Provider itself is generic, not the class it's binding to)

There are a lot of online resources about how to use a Guice Provider to bind to a generic class, such as wiki entries like this and SOF questions like this. However, I am having trouble finding a resource about how to use a Provider that is generic itself.

For example, lets say I have the following:

public interface Foo {
    ...
}

public class Bar implements Foo {
    ...
}

As you can see, Bar has an injection parameter that MUST be in the constructor. In my situation, we cannot move this parameter to field or method injection.

So, now I want to write a Provider for Foo, but that it returns an instance of Bar. Something like this:

@Singleton
public class FooProvider<T extends Foo> extends Provider<Foo> {
    @Inject
    public FooProvider(Object someParameterWeMustInjectIntoConstructor) {
        ...
    }
    ...
    @Override
    public Foo get() {
        return new Bar(...);
    }
    ...
}

Notice how this class is a singleton that relies on Guice injection itself, so the Provider must be configured using .toProvider(FooProvider.class). We also can only use constructor injection and not method nor field injection, possibly because of a type hierarchy with this Provider.

I am trying to find some sort of was to use .toProvider(FooProvider<Bar>.class), but we all know that this is not valid Java syntax. Does anyone know how I can use the .toProvider(Class<? extends Provider>) method of a Guice binder in a Module so I can use a generic Provider to create a concrete class of an implementation? Let me know if my question is a little confusing.

like image 803
ecbrodie Avatar asked Jan 12 '23 04:01

ecbrodie


1 Answers

toProvider(new TypeLiteral<FooProvider<Bar>>() { });
like image 88
Tavian Barnes Avatar answered Jan 22 '23 20:01

Tavian Barnes