基于条件的依赖注入

时间:2020-02-19 10:38:52

标签: java dependency-injection guice

我正在使用策略设计模式,并希望根据某些条件注入不同的依赖关系。

public interface strategy {
    public void task();
}

public class concreteStrategyOne implements strategy {
    public void task() {
        //task strategy one
    }
}

public class concreteStrategyTwo implements strategy {
    public void task() {
        //task strategy two
    }
}

public class taskInHand {

    private Strategy strategyImpl;

    @Inject
    public taskInHand(Strategy strategyImpl){
        this.strategy = strategyImpl;
    }

    public void use(Object obj) {

      if(obj.get("something") == 1){
            strategyImpl.task();
            // I want to call task() implemented in concreteStrategyOne 
      }
      else if(obj.get("something") == 2){
            strategtImpl.task()
            // I want to call task() implemented in concreteStrategyTwo
      }
}

}

我知道我可以在构造函数中使用@Named批注在注入时绑定特定的类,但是我想根据上述条件注入不同的依赖项。

因此,为了详细说明.. if(object.get("something")) returns 1,那么我想运行在task()中实现的concreteStrategyOne

这怎么办?

2 个答案:

答案 0 :(得分:3)

您可以创建一个StrategyFactory

public Class StrategyFactory {
    @Inject
    // Strategy one impl here
    private Strategy strategyOne;

    @Inject
    // Strategy two impl here
    private Strategy strategyTwo;

    public Strategy getStrategy(String something) {
        if (something.equals("some condition")) {
            return strategyOne;
        } else {
            return strategytwo;
        }
    }
}

在您的StrategyFactory中插入taskInHand,然后传递决定用于getStrategy()的实现的属性

public void use(Object obj) {
    strategyFactory.getStrategy(obj.get("something")).task();
}

答案 1 :(得分:1)

您可以使用提供程序(我认为这就是Guice所说的)来选择所需的实现并注入所需的实现。但是您需要向提供商提供做出决定所需的所有信息。这可能会破坏封装和其他一些SOLID创意。

另一种选择是注入所有实现的集合,遍历该集合,并在实现负责或适合特定用例的情况下让实现“ volounteer”。

有关提供商的更多详细信息,请参见guice wiki