Palak Davda
Palak Davda

Reputation: 1

Injecting an object that requires enum in Guice

I have an object to be injected that is defined as:

    public class EnvironmentModule extends AbstractModule {
    
        @Override
        protected void configure() {
        }
    
        @Provides
        @Singleton
        private String getObject(final Client client) {
            ...
        }
}

Client is an enum defined as :

@NoArgsConstructor(force = true)
public enum Client {
    private String name;

    Client(final String name) {
        this.name = name;
    }

    public static Client identifyClient(final String clientName) {
   
    }
}

This gives me an error- Could not find a suitable constructor in Client. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private at Client.class(Client.java:5) at EnvironmentModule.getObject(EnvironmentModule.java:35)

Please help. What has to be done.

Upvotes: 0

Views: 348

Answers (1)

scigs
scigs

Reputation: 624

The reason this is happening is because in your module you do not declare an instance of Client to be injected in the scope of the module, so it tries to create one with an empty constructor. This does not work because your enum has two constructors, and guice requires a single empty constructor. The solution to this to create a singleton of your client. I assume the code you omitted in Client looks like

public enum Client {

    //I assume it works like this
    NORMAL_CLIENT("whatever");

    private String name;

    Client(final String name) {
        this.name = name;
    }

    public static Client identifyClient(final String clientName) {
        return Arrays.stream(Client.values())
            .filter(client -> clientName.equals(client.name))
            .findAny()
            //This is dangerous, throw an error if its not found
            .get();
    }
}

So we need to create a singleton in the environment module for the client. this would look like

public class EnvironmentModule extends AbstractModule {
    @Override
    protected void configure() {
        super.configure();
    }

    @Provides
    @Singleton
    private Client getClient() {
        return Client.identifyClient("whatever");
    }

    @Provides
    @Singleton
    private String doWhatever(final Client client) {
        System.out.println("found client " + client);
        return "cool it works";
    }
}

invoking the module through

public class Main {
    public static void main(String[] args) {
        final var envInjector = Guice.createInjector(new EnvironmentModule());
        final var client = envInjector.getInstance(Client.class);
        final var doWhateverString = envInjector.getInstance(String.class);
        System.out.println(doWhateverString);
        System.out.println("found instance " + client);
    }
}

we can see

found client NORMAL_CLIENT
cool it works
found instance NORMAL_CLIENT

Upvotes: 2

Related Questions