Search code examples
javadependency-injectionguice

Does Guice support a way of method injection (non setter injection)?


From what I understand Guice supports injection for: Constructors, Setters (which they call method injection for some reason), fields.

Can it also inject method parameters? For example:

void foo(InterfaceA a, InterfaceA a1){
    ...
}


interface InterfaceA{
    ...
}


class A implements InterfaceA{
    ....
}

class B implements InterfaceA{
    ....
}

I want to be able to bind a in foo to type A and a1 to B (will probably need annotation but lets ignore that for a second). I want this to be done on invocation.

This seems different from the normal use cases (c'tor, fields, setters) in the sense that the dependency injection will happen on invocation rather than on object creation.

So is this possible?


Solution

  • Well, you can do this:

    Injector injector = Guice.createInjector(b -> {
        b.bind(InterfaceA.class).annotatedWith(Names.named("a")).to(A.class);
        b.bind(InterfaceA.class).annotatedWith(Names.named("a1")).to(B.class);
        b.bind(Invoke.class);
    });
    
    
    public class Invoke {
        private final Injector injector;
    
        @Inject
        Invoke(Injector injector) {
            this.injector = injector;
        }
    
        public void invoke() {
            this.foo(
                injector.getInstance(Key.get(InterfaceA.class, Names.named("a"))),
                injector.getInstance(Key.get(InterfaceA.class, Names.named("a1")))
            );
        }
    
        void foo(InterfaceA a, InterfaceA a1){
            ...
        }
    }
    

    But nothing more. Guice is a dependency injection framework and it usually means "construct objects with all their dependencies". While method parameters are dependencies formally (since the class is supposed to use them - this is the definition of dependency), they are not usually regarded as those by DI frameworks. It is understandable - this would make these frameworks much more complex for little to no gain, and also Java is not expressive enough language for such things not to look obscenely ugly.