Rito
Rito

Reputation: 3290

Injecting Constructor Parameter value using Google Guice

I have a simple requirement -

This is the service where I want to inject the object of CalledService.

public class CallingService {

    private CalledService service;

    @Inject
    public CallingService(CalledService svc) {
        service = svc;
    }
}

The CalledService looks like this -

public class CalledService {

    private String variable_value;

    public CalledService(String parameter) {
        variable_value = parameter;
    }

}

And let's say in the psvm, I am writing this code for execution -

Injector injector = Guice.createInjector(new AppInjector());        
CallingService service = injector.getInstance(CallingService.class);

The issue is if CalledService had a non-parameterised constructor then it would have worked fine. But since it is a parameterised I don’t know how I can inject the parameter value.

Also, several other services might want to inject the CalledService with different parameter values. So I don't want to bind any static value to the parameter.

Can anyone suggest the simplest way this can be achieved using Google Guice? Also, I found a lot of answers in this forum but they were not exactly what I was looking for, and some solutions were overly complicated. Thanks in advance.

Upvotes: 3

Views: 6115

Answers (3)

Rito
Rito

Reputation: 3290

Thanks, @Luigi, and @vsbehere for helping me out. I went through the stackoverflow link which you guys shared before also.

The answer that was mentioned there seemed a bit complicated to me, I wished the way to Inject parameters using Google Guice had been a little simpler. One thing which I was very resistant to use was the factory class and I wanted to know if its usage can be avoided. Then I went through this documentation and I made sense to me.

Just to summarize, the purpose of the FactoryInterface is to help Guice build the objects. AssistedInject maps the create() method's parameters to the corresponding @Assisted parameters in the implementation class's constructor, in this example the implementation class is the CalledService. The create() method in the Factory Interface takes only the assisted parameters and, one should make sure they are in the same order as in the constructor.

I hope the above paragraph made sense, which explains why a Factor class is required. And this is how I solved the above-mentioned problem -

The CalledService now looks like this, there is a @Assisted keyword now in the parameter -

public class CalledService {

    private String variable_value;

    @Inject
    public CalledService(@Assisted String parameter) {
        variable_value = parameter;
    }

    public void printValue() {
        System.out.println(variable_value);
    }
}

The CalledServiceFactory is a new addition, whose purpose is to create objects of CalledService. And this is how it looks -

public interface CalledServiceFactory {

    CalledService create(String var);
}

The CallingService now looks like this, we are injecting a CalledServiceFactory instance to this class now and this will help in creating the instance of CalledService -

public class CallingService {

    @Inject
    private CalledServiceFactory factory;

    public void callingMethod() {
        CalledService service = factory.create("someValue");
        service.printValue();
    }
}

Inside the Module, I have configured the CalledServiceFactory -

public class AppInjector extends AbstractModule {

    @Override
    protected void configure() {
        install(new FactoryModuleBuilder()
                 .build(CalledServiceFactory.class));
    }
}

And finally, for executing it, this is how I have executed it in the main function -

private static void main() {
        Injector injector = Guice.createInjector(new AppInjector());
        CallingService service = injector.getInstance(CallingService.class);
        service.callingMethod();
}

This is how I have implemented it, and this is the max simplest I could trim it down to. If anyone has any optimum solution then please let me know.

Upvotes: 1

weiglt
weiglt

Reputation: 1079

I'm afraid you took a wrong turn. Look at provides-methods instead (also, use interface binding to unleash Guice' full potential!):

import javax.swing.JOptionPane;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Provides;

public class Main {

    public static void main(String[] args) {

        CallingService callingService = Guice.createInjector(new AbstractModule() {

            @Override
            protected void configure() {
                bind(CallingService.class).to(DefaultCallingService.class);
                bind(CalledService.class).to(DefaultCalledService.class);
            }

            @Provides
            String provideParameter() {
                return JOptionPane.showInputDialog(null);
            }

        }).getInstance(CallingService.class);

        callingService.requestStuffExecution();
    }
}

Interface 1:

public interface CallingService {

    void requestStuffExecution();
}

Interface 2:

public interface CalledService {

    void doStuff();
}

Default Impl1:

import com.google.inject.Inject;

public class DefaultCallingService implements CallingService {

    private DefaultCalledService service;

    @Inject
    public DefaultCallingService(DefaultCalledService svc) {
        service = svc;
    }

    @Override
    public void requestStuffExecution() {
        service.doStuff();
    }
}

Default Impl2:

import com.google.inject.Inject;

public class DefaultCalledService implements CalledService {

    private String parameter;

    @Inject
    public DefaultCalledService(String par) {
        this.parameter = par;
    }

    @Override
    public void doStuff() {
        System.out.println("Oh boy, always so much stuff to do! Performing: " + parameter);
    }
}

Prints: "Oh boy, always so much stuff to do! Performing: <The Input String>".

Upvotes: 0

Luigi
Luigi

Reputation: 124

In addition to the suggestion in the comment above - assisted inject You can bind instances in Guice. Please see here for details/examples

Hope this helps

Upvotes: 1

Related Questions