Schumi
Schumi

Reputation: 33

Guice instantiate different classes with different providers

I have two activities

public class GetActivity
{
    ChildClass childclass;

    @Inject
    public GetActivity(ChildClass childClass)
    {
        this.childClass = childclass;
    }
    String id = childClass.get(id);
    ....
}

public class SaveActivity
{
    ChildClass childclass;

    @Inject
    public SaveActivity(ChildClass childClass)
    {
        this.childClass = childclass;
    }
    childClass.save(id);
    ....
}

ChildClass is an interface with the following methods

public interface ChildClass
{
    String get(id);
    void save(id);
}

and its implemented as the following

public class ChildClassImpl implements ChildClass
{
    String storage;

    public ChildClassImpl(String storage)
    {
        this.storage =storage;
    }

    String get(Id)
    {
       someOtherObject.get(id, storage);
    }

    void save(id)
    {
       someOtherObject.save(id, storage);
    }
}

I wrote providers which will return the ChildClass method

public class ChildClassProvider1 implements Provider<ChildClass>
{
    @Override
    public ChildClass get()
    {
      ChildClass childClass = new ChildClass("hello");
    }
}

public class ChildClassProvider2 implements Provider<ChildClass>
{
    @Override
    public ChildClass get()
    {
      ChildClass childClass = new ChildClass("secondHello");
    }
}

I want to make sure that GetActivity and SaveActivity are initialzied with the provider ChildClassProvider1 but the other classes should use ChildClassProvider2. How to achieve this with guice?

Upvotes: 1

Views: 443

Answers (1)

Andy Turner
Andy Turner

Reputation: 140554

A couple of options, depending upon how hard you want to bake this requirement into your code.

Firstly, via a provides method In your module:

class YourModule extends AbstractModule {
  @Override protected void configure() {
    bind(ChildClass.class).toProvider(ChildClassProvider1.class);
  }

  @Provides SaveAction saveAction(ChildClassProvider2 provider) {
    return new SaveAction(provider.get());
  }
}

Secondly, via a binding annotation Or, provide a binding annotation:

@BindingAnnotation @Retention(RUNTIME)
@interface YourAnnotation {}

Then:

// Ctor of SaveActivity.
@Inject
public SaveActivity(@YourAnnotation ChildClass childClass) { ... }

// In your module:
bind(ChildClass.class).annotatedWith(YourAnnotation.class)
    .toProvider(ChildClassProvider2.class);

The second option is "baking it in harder", because you have to put the binding annotation in the code; but it's a little less brittle (in the sense that you don't have to explicitly call the constructor), and feels "more guice-y".

The first option is keeping it a little looser, should you want to be able to configure things differently in certain circumstances.

Upvotes: 1

Related Questions