Guice with multiple concretes…picking one of them

后端 未结 1 1101
时光取名叫无心
时光取名叫无心 2020-12-22 09:00

I am injection multiple concretes of the same interface.

I figured out the Guide \"code it up\" convention.

My code currently spits out

[INFO         


        
1条回答
  •  南方客
    南方客 (楼主)
    2020-12-22 09:39

    If you use Multibinder for map bindings, then you could bind each of the Shipper instances into a Map using MapBinder:

    MapBinder multibinder = MapBinder.newMapBinder(
        binder(), String.class, ShipperInterface.class);
    multibinder.addBinding("FedEx").to(FedExShipper.class);
    multibinder.addBinding("UPS").to(UpsShipper.class);
    multibinder.addBinding("USPS").to(UspsShipper.class);
    

    Then in your injected class you can inject a Map>:

    private ShipperInterface FindShipperInterface(String 
        preferredShipperAbbreviation) {
    
      ShipperInterface foundShipperInterface =
          providerMap.get(preferredShipperAbbreviation).get();
    }
    

    You could also inject a Map directly, but Multibinder handles the Provider indirection for free, which lets you avoid creating three ShipperInterface instances when only one will actually be necessary. Also, if your instance-selection code is more complicated than simply choosing based on a String from a set of implementations you know at compile time, you might still want a Factory implementation you write.


    As a side note, ideally use @Inject annotations and bind(...).to(...) instead of toConstructor. This doesn't tie you to Guice, because @Inject is defined in JSR-330, and you are adding annotations that you can choose not to use later. You can also write a @Provides method in your AbstractModule, like so, which is no more fragile than your toConstructor bindings:

    @Provides UspsShipper provideUspsShipper(Log log) {
      return new UspsShipper(log);
    }
    

    Use toConstructor if and only if you are using legacy code, code you don't control, very restrictive code style rules, or AOP (which may be the case here). I've done so above for the sake of a concise example, but you can revert to toConstructor if necessary.

    0 讨论(0)
提交回复
热议问题