Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guice: How to do late binding?

Tags:

java

guice

I am trying to so some late binding using Google Guice.

public class MyClassProvider implements Provider<MyClass>{
    private DependencyClass dep;
    private WebService webservice;

    @Inject
    MyClassProvider(DependencyClass dep, WebService webservice){
        this.dep = dep;
        this.webservice = webservice;
    }

    public MyClass get() {
        MyClass myclass = webservice.call(dep);
    }
}

I have a binding in the module:

   bind(MyClass.class).toProvider(MyClassProvider.class).in(ServletScopes.REQUEST);

I have another class ConsumerClass, which needs to use MyClass. Here the problem comes, because dep will be null until a certain point, I won't be able to Inject MyClass to ConsumerClass, I therefore injected Provider.

public class ConsumerClass {
    private MyClassProvider myClassProvider;

    @Inject
    public ConsumerClass(Provider<MyClass> myClassProvider){
       this.myClassProvider = myClassProvider;
    }

    ......

    public void myfunction() {
        // Here dep is initialized and become non-null here.

        // Then, I call
        MyClass myClass = myClassProvider.get();

    }
}

The problem I have is that when I inject MyClassProvider to the ConsumerClass, it tried to create an instance of MyClassProvider, because dep is null at that time, it failed. Annotating it as @Nullable does not solve my problem as I need dep in the get() method of the provider anyway.

Is there any ways to let Guice create the provider instance only when the get() method is called? Or is there any other work around on this problem?

Many thanks.


Jeff: Thanks for your reply.

Do you mean I can change my code to something like:

public class MyClassProvider implements Provider<MyClass>{
        private Provider<DependencyClass> depProvider;
        private WebService webservice;

        @Inject
        MyClassProvider(Provider<DependencyClass> depProvider, WebService webservice){
            this.depProvider = depProvider;
            this.webservice = webservice;
        }

        public MyClass get() {
            DependencyClass dep = depProvider.get(); 
            MyClass myclass = webservice.call(dep);
        }
    }
like image 979
Kevin Avatar asked Oct 21 '22 17:10

Kevin


1 Answers

Replace DependencyClass with Provider<DependencyClass>. Guice does not require toProvider or a @Provides method in order to access a Provider for any type Guice can provide.

This way dep will only need to be provided when MyProvider is called, not instantiated.

like image 97
Jeff Bowman Avatar answered Oct 27 '22 11:10

Jeff Bowman