CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-google-inject-extensions--guice-multibindings

Extension for binding multiple instances in a collection with Set, Map, and Optional binding capabilities.

Pending
Overview
Eval results
Files

set-binding.mddocs/

Set Binding (Multibinder)

Set binding functionality that allows multiple modules to contribute elements to a single Set collection. Elements are bound individually and then injected as a complete Set, enabling plugin-style architectures where multiple independent modules can extend functionality.

Capabilities

Multibinder Factory Methods

Creates new Multibinder instances for different type and annotation combinations.

/**
 * Returns a new multibinder that collects instances of type in a Set 
 * that is itself bound with no binding annotation.
 */
public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type);

/**
 * Returns a new multibinder that collects instances of type in a Set 
 * that is itself bound with no binding annotation.
 */
public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type);

/**
 * Returns a new multibinder that collects instances of type in a Set 
 * that is itself bound with annotation.
 */
public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type, Annotation annotation);

/**
 * Returns a new multibinder that collects instances of type in a Set 
 * that is itself bound with annotation.
 */
public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type, Annotation annotation);

/**
 * Returns a new multibinder that collects instances of type in a Set 
 * that is itself bound with annotationType.
 */
public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type, Class<? extends Annotation> annotationType);

/**
 * Returns a new multibinder that collects instances of type in a Set 
 * that is itself bound with annotationType.
 */
public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type, Class<? extends Annotation> annotationType);

/**
 * Returns a new multibinder that collects instances of the key's type in a Set 
 * that is itself bound with the annotation (if any) of the key.
 */
public static <T> Multibinder<T> newSetBinder(Binder binder, Key<T> key);

Element Binding

Add elements to the Set collection.

/**
 * Returns a binding builder used to add a new element in the set. Each bound element 
 * must have a distinct value. Bound providers will be evaluated each time the set is injected.
 * 
 * It is an error to call this method without also calling one of the to methods on the 
 * returned binding builder. Scoping elements independently is supported.
 */
public LinkedBindingBuilder<T> addBinding();

Duplicate Handling

Configure how duplicate elements are handled.

/**
 * Configures the bound set to silently discard duplicate elements. When multiple equal 
 * values are bound, the one that gets included is arbitrary. When multiple modules 
 * contribute elements to the set, this configuration option impacts all of them.
 */
public Multibinder<T> permitDuplicates();

Provider Method Support

Contribute elements using provider methods with the @ProvidesIntoSet annotation.

/**
 * Annotates methods of a Module to add items to a Multibinder. The method's return 
 * type and binding annotation determines what Set this will contribute to.
 */
@Target(METHOD)
@Retention(RUNTIME)
public @interface ProvidesIntoSet {}

Usage Examples:

Basic Set Binding:

public class SnacksModule extends AbstractModule {
  @Override
  protected void configure() {
    Multibinder<Snack> multibinder = Multibinder.newSetBinder(binder(), Snack.class);
    multibinder.addBinding().toInstance(new Twix());
    multibinder.addBinding().toProvider(SnickersProvider.class);
    multibinder.addBinding().to(Skittles.class);
  }
}

// Injection
@Inject
public SnackMachine(Set<Snack> snacks) {
  this.snacks = snacks; // Contains Twix, Snickers, Skittles
}

Annotated Set Binding:

public class WebServicesModule extends AbstractModule {
  @Override
  protected void configure() {
    Multibinder<RequestHandler> multibinder = Multibinder.newSetBinder(
        binder(), RequestHandler.class, Names.named("web"));
    multibinder.addBinding().to(UserRequestHandler.class);
    multibinder.addBinding().to(OrderRequestHandler.class);
  }
}

// Injection
@Inject
public WebServer(@Named("web") Set<RequestHandler> handlers) {
  this.handlers = handlers;
}

Provider Method Binding:

public class ServicesModule extends AbstractModule {
  @ProvidesIntoSet
  RequestHandler provideUserHandler(UserService userService) {
    return new UserRequestHandler(userService);
  }
  
  @ProvidesIntoSet
  @Named("web")
  RequestHandler provideWebHandler() {
    return new WebRequestHandler();
  }
}

Provider Collection Injection:

// Can also inject Collection<Provider<T>> for lazy evaluation
@Inject 
public SnackMachine(Collection<Provider<Snack>> snackProviders) {
  this.snackProviders = snackProviders;
}

Multiple Modules Contributing:

// CandyModule
public class CandyModule extends AbstractModule {
  @Override
  protected void configure() {
    Multibinder<Snack> multibinder = Multibinder.newSetBinder(binder(), Snack.class);
    multibinder.addBinding().to(Chocolate.class);
    multibinder.addBinding().to(Gummies.class);
  }
}

// ChipsModule  
public class ChipsModule extends AbstractModule {
  @Override
  protected void configure() {
    Multibinder<Snack> multibinder = Multibinder.newSetBinder(binder(), Snack.class);
    multibinder.addBinding().to(Doritos.class);
    multibinder.addBinding().to(Cheetos.class);
  }
}

// Final injected Set contains elements from both modules

Duplicate Handling:

public class ConfigModule extends AbstractModule {
  @Override
  protected void configure() {
    Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class)
        .permitDuplicates(); // Allow duplicate values
    multibinder.addBinding().toInstance("config1");
    multibinder.addBinding().toInstance("config1"); // Would normally fail without permitDuplicates()
  }
}

Key Features

  • Element Uniqueness: By default, elements must be distinct or injection will fail
  • Iteration Order: Set iteration order is consistent with binding order within a module
  • Multi-Module Support: Multiple modules can contribute to the same Set
  • Provider Support: Can inject Collection<Provider<T>> for lazy evaluation
  • Scoping: Individual elements can be scoped independently
  • Annotation Support: Different Sets of same type can be created using binding annotations

Install with Tessl CLI

npx tessl i tessl/maven-com-google-inject-extensions--guice-multibindings

docs

index.md

map-binding.md

optional-binding.md

set-binding.md

tile.json