简体   繁体   中英

How to get a list of objects from Guice by their classes?

I defined some "transformers" (functions) and need a list of them. Each of them gets created by Guice and I'm using this code to get the list:

public class CombinedTransformer extends AbstractTransformer {
    @Inject CombinedTransformer(
            FirstTransformer firstTransformer,
            SecondTransformer secondTransformer,
            ThirdTransformer thirdTransformer) {
        transformers = ImmutableList.of(
                firstTransformer,
                secondTransformer,
                thirdTransformer);

My list is pretty long, so I wonder if there's a simpler way, something like

public class CombinedTransformer extends AbstractTransformer {
    @Inject CombinedTransformer(Injector injector) {
        transformers = injector.getList(
            FirstTransformer.class,
            SecondTransformer.class,
            ThirdTransformer.class);
    }
}

Is there something like this?

You can use multibindings for this:

Multibinder<AbstractTransformer> multibinder = Multibinder.newSetBinder(binder(), AbstractTransformer.class);
multibinder.addBinding().to(FirstTransformer.class);
multibinder.addBinding().to(SecondTransformer.class);
multibinder.addBinding().to(ThirdsTransformer.class);

Then you can inject Set<AbstractTransformer> :

@Inject
CombinedTransformer(Set<AbstractTransformer> transformers) {
    // do whatever you want with the set
}

But you can't do it without using multibindings directly. If you really need to get a list of objects using statically known list of classes, you can write a wrapper around an injector and use it:

public class ListInjectorWrapper {
    private final Injector injector;

    @Inject
    ListInjectorWrapper(Injector injector) {
        this.injector = injector;
    }

    @SafeVarargs
    public final <T> List<T> getList(Class<? extends T>... classes) {
        return Arrays.stream(classes).map(clazz -> injector.getInstance(clazz))
            .collect(Collectors.toList());
    }
}

Then inject it and use it to get your transformers:

@Inject
CombinedTransformer(ListInjectorWrapper injectorWrapper) {
    transformers = injectorWrapper.getList(
        FirstTransformer.class,
        SecondTransformer.class,
        ThirdTransformer.class
    );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM