Guice: One “Provider” for multiple implementations

后端 未结 2 1365
夕颜
夕颜 2021-01-16 15:28

I have an interface that has 20 or so annotated implementations. I can inject the correct one if I know which I need at compile time, but I now need to dynamically inject on

2条回答
  •  清酒与你
    2021-01-16 16:09

    If all you want is to get an instance programmatically, you can inject an Injector. It's rarely a good idea--injecting a Provider is a much better idea where you can, especially for the sake of testing--but to get a binding reflectively it's the only way to go.

    class YourClass {
      final YourDep yourDep;  // this is the dep to get at runtime
    
      @Inject YourClass(Injector injector) {
        YourAnnotation annotation = deriveYourAnnotation();
        // getProvider would work here too.
        yourDep = injector.getInstance(Key.get(YourDep.class, annotation));
      }
    }
    

    If you're trying write a Provider that takes a parameter, the best way to express this is to write a small Factory.

    class YourDepFactory {
      @Inject @A Provider aProvider;
      @Inject @B Provider bProvider;
      // and so forth
    
      Provider getProvider(YourParameter parameter) {
        if (parameter.correspondsToA()) {
          return aProvider;
        } else if (parameter.correspondsToB()) {
          return bProvider;
        }
      }
    
      YourDep get(YourParameter parameter) {
        return getProvider(parameter);
      }
    }
    

提交回复
热议问题