Extension for binding multiple instances in a collection with Set, Map, and Optional binding capabilities.
npx @tessl/cli install tessl/maven-com-google-inject-extensions--guice-multibindings@4.2.00
# Google Guice Multibindings
1
2
Google Guice Multibindings is a dependency injection extension that enables flexible plugin-style architectures by allowing multiple modules to contribute implementations to a single collection. It provides three key binding mechanisms: Multibinder for adding multiple implementations to a Set, MapBinder for adding key-value pairs to a Map, and OptionalBinder for optional binding capabilities with default value support.
3
4
## Package Information
5
6
- **Package Name**: guice-multibindings
7
- **Package Type**: maven
8
- **Language**: Java
9
- **Group ID**: com.google.inject.extensions
10
- **Artifact ID**: guice-multibindings
11
- **Version**: 4.2.3
12
- **Installation**:
13
```xml
14
<dependency>
15
<groupId>com.google.inject.extensions</groupId>
16
<artifactId>guice-multibindings</artifactId>
17
<version>4.2.3</version>
18
</dependency>
19
```
20
21
## Core Imports
22
23
```java
24
import com.google.inject.multibindings.Multibinder;
25
import com.google.inject.multibindings.MapBinder;
26
import com.google.inject.multibindings.OptionalBinder;
27
```
28
29
For provider method annotations:
30
31
```java
32
import com.google.inject.multibindings.ProvidesIntoSet;
33
import com.google.inject.multibindings.ProvidesIntoMap;
34
import com.google.inject.multibindings.ProvidesIntoOptional;
35
import com.google.inject.multibindings.StringMapKey;
36
import com.google.inject.multibindings.ClassMapKey;
37
import com.google.inject.multibindings.MapKey;
38
```
39
40
For binding introspection:
41
42
```java
43
import com.google.inject.multibindings.MultibinderBinding;
44
import com.google.inject.multibindings.MapBinderBinding;
45
import com.google.inject.multibindings.OptionalBinderBinding;
46
import com.google.inject.multibindings.MultibindingsTargetVisitor;
47
```
48
49
## Basic Usage
50
51
```java
52
import com.google.inject.AbstractModule;
53
import com.google.inject.multibindings.Multibinder;
54
import com.google.inject.multibindings.MapBinder;
55
import com.google.inject.multibindings.OptionalBinder;
56
57
public class SnacksModule extends AbstractModule {
58
@Override
59
protected void configure() {
60
// Set binding
61
Multibinder<Snack> multibinder =
62
Multibinder.newSetBinder(binder(), Snack.class);
63
multibinder.addBinding().to(Twix.class);
64
multibinder.addBinding().to(Snickers.class);
65
66
// Map binding
67
MapBinder<String, Snack> mapbinder =
68
MapBinder.newMapBinder(binder(), String.class, Snack.class);
69
mapbinder.addBinding("twix").to(Twix.class);
70
mapbinder.addBinding("snickers").to(Snickers.class);
71
72
// Optional binding
73
OptionalBinder<Renamer> optionalBinder =
74
OptionalBinder.newOptionalBinder(binder(), Renamer.class);
75
optionalBinder.setDefault().to(DefaultRenamer.class);
76
}
77
}
78
79
// Usage with provider methods
80
public class ProvidersModule extends AbstractModule {
81
@ProvidesIntoSet
82
Snack provideChocolate() { return new Chocolate(); }
83
84
@ProvidesIntoMap
85
@StringMapKey("sweet")
86
Snack provideSweetSnack() { return new Candy(); }
87
88
@ProvidesIntoOptional(ProvidesIntoOptional.Type.DEFAULT)
89
Logger provideDefaultLogger() { return new ConsoleLogger(); }
90
}
91
```
92
93
## Architecture
94
95
Guice Multibindings is built around three core concepts:
96
97
- **Collection Binding**: Multiple independent modules can contribute to the same collection without knowing about each other
98
- **Type Safety**: Full compile-time type checking for all bindings and injections
99
- **Lazy Evaluation**: Elements are resolved at injection time, supporting scoped bindings and providers
100
- **Annotation Support**: Different collections of the same type can be distinguished using binding annotations
101
102
The API supports both imperative binding (using binder methods in configure()) and declarative binding (using @Provides annotations with special multibinding annotations).
103
104
## Capabilities
105
106
### Set Binding (Multibinder)
107
108
Creates collections where multiple modules can contribute elements to a single Set. Ideal for plugin architectures, event handlers, and extensible service registries.
109
110
```java { .api }
111
public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type);
112
public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type);
113
public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type, Annotation annotation);
114
public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type, Annotation annotation);
115
public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type, Class<? extends Annotation> annotationType);
116
public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type, Class<? extends Annotation> annotationType);
117
public static <T> Multibinder<T> newSetBinder(Binder binder, Key<T> key);
118
119
public Multibinder<T> permitDuplicates();
120
public LinkedBindingBuilder<T> addBinding();
121
```
122
123
[Set Binding](./set-binding.md)
124
125
### Map Binding (MapBinder)
126
127
Creates key-value collections where multiple modules can contribute entries to a single Map. Perfect for registries, configuration systems, and named service lookups.
128
129
```java { .api }
130
public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, Class<K> keyType, Class<V> valueType);
131
public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, TypeLiteral<K> keyType, TypeLiteral<V> valueType);
132
public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, Class<K> keyType, Class<V> valueType, Annotation annotation);
133
public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, TypeLiteral<K> keyType, TypeLiteral<V> valueType, Annotation annotation);
134
public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, Class<K> keyType, Class<V> valueType, Class<? extends Annotation> annotationType);
135
public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, TypeLiteral<K> keyType, TypeLiteral<V> valueType, Class<? extends Annotation> annotationType);
136
137
public MapBinder<K, V> permitDuplicates();
138
public LinkedBindingBuilder<V> addBinding(K key);
139
```
140
141
[Map Binding](./map-binding.md)
142
143
### Optional Binding (OptionalBinder)
144
145
Creates optional dependencies with default value support. Allows frameworks to define extension points that users can optionally override.
146
147
```java { .api }
148
public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, Class<T> type);
149
public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, TypeLiteral<T> type);
150
public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, Key<T> type);
151
152
public LinkedBindingBuilder<T> setDefault();
153
public LinkedBindingBuilder<T> setBinding();
154
```
155
156
[Optional Binding](./optional-binding.md)
157
158
### Binding Introspection (Visitor Pattern)
159
160
Enables advanced introspection of multibinding configurations using the visitor pattern. Useful for tools, debuggers, and frameworks that need to analyze binding structure.
161
162
```java { .api }
163
public interface MultibindingsTargetVisitor<T, V> extends BindingTargetVisitor<T, V> {
164
/** Visits a binding created through Multibinder. */
165
V visit(MultibinderBinding<? extends T> multibinding);
166
167
/** Visits a binding created through MapBinder. */
168
V visit(MapBinderBinding<? extends T> mapbinding);
169
170
/** Visits a binding created through OptionalBinder. @since 4.0 */
171
V visit(OptionalBinderBinding<? extends T> optionalbinding);
172
}
173
```
174
175
## Types
176
177
```java { .api }
178
// Annotation for contributing to Sets via provider methods
179
@Target(METHOD)
180
@Retention(RUNTIME)
181
public @interface ProvidesIntoSet {}
182
183
// Annotation for contributing to Maps via provider methods
184
@Target(METHOD)
185
@Retention(RUNTIME)
186
public @interface ProvidesIntoMap {}
187
188
// Annotation for contributing to Optionals via provider methods
189
@Target(METHOD)
190
@Retention(RUNTIME)
191
public @interface ProvidesIntoOptional {
192
enum Type { ACTUAL, DEFAULT }
193
Type value();
194
}
195
196
// Meta-annotation for creating custom map key annotations
197
@Target(ANNOTATION_TYPE)
198
@Retention(RUNTIME)
199
public @interface MapKey {
200
boolean unwrapValue() default true;
201
}
202
203
// Built-in map key annotation for String keys
204
@MapKey(unwrapValue = true)
205
@Target(METHOD)
206
@Retention(RUNTIME)
207
public @interface StringMapKey {
208
String value();
209
}
210
211
// Built-in map key annotation for Class keys
212
@MapKey(unwrapValue = true)
213
@Target(METHOD)
214
@Retention(RUNTIME)
215
public @interface ClassMapKey {
216
Class<?> value();
217
}
218
219
// Binding information interfaces for introspection
220
public interface MultibinderBinding<T> {
221
Key<T> getSetKey();
222
Set<Key<?>> getAlternateSetKeys();
223
TypeLiteral<?> getElementTypeLiteral();
224
List<Binding<?>> getElements();
225
boolean permitsDuplicates();
226
boolean containsElement(Element element);
227
}
228
229
public interface MapBinderBinding<T> {
230
Key<T> getMapKey();
231
Set<Key<?>> getAlternateMapKeys();
232
TypeLiteral<?> getKeyTypeLiteral();
233
TypeLiteral<?> getValueTypeLiteral();
234
List<Map.Entry<?, Binding<?>>> getEntries();
235
List<Map.Entry<?, Binding<?>>> getEntries(Iterable<? extends Element> elements);
236
boolean permitsDuplicates();
237
boolean containsElement(Element element);
238
}
239
240
public interface OptionalBinderBinding<T> {
241
Key<T> getKey();
242
Set<Key<?>> getAlternateKeys();
243
Binding<?> getDefaultBinding();
244
Binding<?> getActualBinding();
245
boolean containsElement(Element element);
246
}
247
```