NewJ
NewJ

Reputation: 389

Dependency injection with Guice for several implementations of same interface

I'd like to try to use Guice in my project, and stucked on simple(from my point of view) problem.

Assume that i have interface

public interface TradeService {
        public boolean buy(Player player, ProductID productId);
}

which have several implementations with it's dependencies:

 public CarsTradeService implements TradeService {
      //...implementation here...
    }

    public BoatsTradeService implements TradeService {
      //...implementation here...
    }

    public AirplanesTradeService implements TradeService {
      //...implementation here...
    }

I understand how to configure implementations and provide needed dependencies for them - to do this i need to create guice "modules" which will look like

public class CarsTradeModule extends AbstractModule {
    @Override 
    protected void configure() {
     bind(TradeService.class).to(CarsTradeService.class).in(Singleton.class);
    }
}

And similar modules to rest two services. Ok, modules builded. But later, when i need to inject this implementations to some class - how could i inject exactly needed implementation?

For example, if i need to get instance of CarsTradeService - how could i get exactly this instance?

Upvotes: 2

Views: 2701

Answers (2)

ste-xx
ste-xx

Reputation: 350

You can use guice multi binding. It is a guice extension.

https://github.com/google/guice/wiki/Multibindings

@Override
public void configure() {
  Multibinder.newSetBinder(binder(),TradeService.class)
  .addBinding()
  .to(CarsTradeService.class);

  Multibinder.newSetBinder(binder(),TradeService.class)
  .addBinding()
  .to(BoatsTradeService.class);

  Multibinder.newSetBinder(binder(),TradeService.class)
  .addBinding()
  .to(AirplanesTradeService.class);
}

Upvotes: 1

Kaushik Chakraborty
Kaushik Chakraborty

Reputation: 699

You can use annotatedWith and @Named for doing exactly that.

bind(TradeService.class).annotatedWith(Names.named("carsTradeService")).to(CarsTradeService.class).in(Singleton.class);

And in the class you want to inject this bean you need to use

@Inject
@Named("carsTradeService")
private TradeService tradeService;

This will inject the exact class you need.

Upvotes: 3

Related Questions