Search code examples
bindingannotationsguice

Google Guice binding using Annotation and Key class


Lets say we have A.java interface implemented by AImpl.java and B.java implemented by Bimpl.java

Above classes are binded in two modules as below

Module1 {
    bind(A.class).to(AImpl.class);
    bind(B.class).to(BImpl.class);
}

Module2 {
    Key<A> aKey = Key.get(A.class, AnAnnot.class);
    bind(aKey).to(AImpl.class);
    Key<B> bKey = Key.get(B.class, AnAnnot.class);
    bind(bKey).to(BImpl.class);
}


Class AImpl implements A {
}

Class BImpl implements B {

@Inject
BImpl(A aImpl) {
 //??
}
}

BImpl refers to A

For BImpl binded using Annotation, I want corresponding aImpl, binded using Annotation but here I'm getting aImpl which is not binded using Annotation

Please suggest


Solution

  • I'm able to achieve using below pattern. May be there is a more easier way. Happy to know more

    A.java

    public interface A {
        String aMethod();
    }
    

    AImpl.java

    public class AImpl implements A {
    
        private String moduleName;
    
        public AImpl(String moduleName) {
            this.moduleName = moduleName;
        }
    
        @Override
        public String aMethod() {
            return moduleName;
        }
    }
    

    B.java

    public interface B {
        String bMethod();
    }
    

    Bimpl.java

    public class BImpl implements B {
        private final A a;
    
        BImpl(A a) {
            this.a = a;
        }
    
        @Override
        public String bMethod() {
            return a.aMethod();
        }
    }
    

    AnAnnot.java

    @Target(PARAMETER)
    @Retention(RUNTIME)
    @BindingAnnotation
    public @interface AnAnnot {
    }
    

    BProvider.java

    public class BProvider  implements Provider<B> {
        private final A a;
    
        @Inject
        BProvider(A a) {
            this.a = a;
        }
    
        @Override
        public B get() {
            return new BImpl(a);
        }
    }
    

    BHavingAnnotatedA.java

    public class BHavingAnnotatedA implements Provider<B> {
        private final A a;
    
        @Inject
        BHavingAnnotatedA(@AnAnnot A a) {
            this.a = a;
        }
    
        @Override
        public B get() {
            return new BImpl(a);
        }
    }
    

    ABModule1.java

    public class ABModule1 extends AbstractModule {
    
        @Override
        protected void configure() {
            bind(A.class).to(AImpl.class);
            bind(B.class).toProvider(BProvider.class);
        }
    }
    

    ABModule2.java

    public class ABModule2 extends AbstractModule {
    
        @Override
        protected void configure() {
            Key<A> aKey = Key.get(A.class, AnAnnot.class);
            bind(aKey).to(AImpl.class);
            Key<B> bKey = Key.get(B.class, AnAnnot.class);
            bind(bKey).toProvider(BHavingAnnotatedA.class);
        }
    }