javadependency-injectionguicestrategy-pattern

Implement Strategy pattern with Guice DI


I am very new in Guice DI. I am trying to implement a Strategy pattern with Guice. But I am confused on, How to inject different types of Strategy Implementations in the Context class through Guice DI. Can any expert help me on this. Following are my codes till now.

The Strategy Pattern

public interface MetricCollectorStrategy {
    List<String> collect(final Context context);
}

public class AMetricCollector implements MetricCollectorStrategy {
 @Override
 public List<String> collect(final Context context) {
    List<String> aMetricList = construct A metric list by some business logic....
    return aMetricList;
 }
}


public class BMetricCollector implements MetricCollectorStrategy {
 @Override
 public List<String> collect(final Context context) {
    List<String> bMetricList = construct B metric list by some business logic....
    return bMetricList;
 }
}


@AllArgsConstructor(onConstructor_ = @Inject)
public class MetricPublisher {

    // This has a method to publish metric
    private final MetricsHelper metricsHelper;
    private final MetricCollectorStrategy metricCollectorStrategy;

 
    public void collectAndPublishMetric(Context context) {
        metricsHelper.emitCollectedCountMetricList(metricCollectorStrategy.collect(context));
    }
}

Till then it's fine. But how to create and inject these 2 types of MetricCollector in the client:

@AllArgsConstructor(onConstructor_ = @Inject)
public class Client{
    
  // Some dummy code to simulate the current code
  private final ExistingDependency_1 existingDependency_1;

  private final ExistingDependency_2 existingDependency_2;

  private final ExistingDependency_3 existingDependency_2;


  // Now how to create the metricCollectors here

  AMetricCollector aMetricCollector;
  BMetricCollector bMetricCollector;

  public void someMethod(Context context){


      if(condition){
        aMetricCollector.collectAndPublishMetric(context);
      }else{
        bMetricCollector.collectAndPublishMetric(context);
      }
  }

}



Solution

  • Note that the spot where you say

    // Now how to create the metricCollectors here

    is not where you should actually create the metricCollectors. That's the point of Dependency Injection, you inject your dependencies rather than constructing them.

    You should instead have a constructor where you receive those dependencies and your DI framework should create them.