Vinculando o mesmo parâmetro a várias implementações com MultiBinder e Asisstedinjection da Guice

Nov 08 2020

Tenho um conjunto de classes validadoras que estendem uma classe abstrata comum, todas com o mesmo construtor

public abstract class AbstractValidator {
    public AbstractValidator(DataSource dataSource) {
        // ...
    }
}

public class Validator1 extends AbstractValidator {
    public Validator1(DataSource dataSource) {
        super(dataSource);
    }
}

public class Validator2 extends AbstractValidator {
    public Validator2(DataSource dataSource) {
        super(dataSource);
    }
}

Eu quero a habilidade do Guice para

  1. Saiba como construir todos esses validadores, injetando o mesmo DataSource em todos eles
  2. Injetar todos os validadores em uma classe usando um MultiBinder

Pesquisando no Google, parecia que eu poderia usar AssistedInject, mas o problema é que se eu quisesse fazer isso, teria que fazer uma fábrica para cada validador, que é uma grande quantidade de clichê. Como todos eles têm o mesmo construtor, acho que deve haver uma maneira melhor. Meu DataSourceobjeto foi criado fora do Guice e eu só quero vinculá-lo a todas as instâncias de DataSource.classno meu configure.

Uma coisa que estou disposto a mudar é ter algum tipo de método de fábrica que me permita criar um validador a partir de apenas um DataSource... Reconheço que meu desejo de usar construtores pode não ser seguro para tipos.

Essa resposta se parece quase com o que eu quero, mas está em Scala, com a qual não estou familiarizado o suficiente para entender totalmente.

Respostas

1 OlivierGrégoire Nov 08 2020 at 17:25

Não há necessidade de AssistedInject.

Você pode vincular sua instância DataSourceassim:

DataSource dataSource = ...;
Injector injector = Guice.createInjector(new AbstractModule() {
  @Provides @Singleton DataSource provideDataSource() { return dataSource; }
  @ProvidesIntoSet Validator provideValidator1(DataSource dataSource) { return new Validator1(dataSource); }
  @ProvidesIntoSet Validator provideValidator2(DataSource dataSource) { return new Validator2(dataSource); }
});

Set<Validator> validators = injector.get(new Key<Set<Validator>>(){});