0
# Set Binding (Multibinder)
1
2
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.
3
4
## Capabilities
5
6
### Multibinder Factory Methods
7
8
Creates new Multibinder instances for different type and annotation combinations.
9
10
```java { .api }
11
/**
12
* Returns a new multibinder that collects instances of type in a Set
13
* that is itself bound with no binding annotation.
14
*/
15
public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type);
16
17
/**
18
* Returns a new multibinder that collects instances of type in a Set
19
* that is itself bound with no binding annotation.
20
*/
21
public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type);
22
23
/**
24
* Returns a new multibinder that collects instances of type in a Set
25
* that is itself bound with annotation.
26
*/
27
public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type, Annotation annotation);
28
29
/**
30
* Returns a new multibinder that collects instances of type in a Set
31
* that is itself bound with annotation.
32
*/
33
public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type, Annotation annotation);
34
35
/**
36
* Returns a new multibinder that collects instances of type in a Set
37
* that is itself bound with annotationType.
38
*/
39
public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type, Class<? extends Annotation> annotationType);
40
41
/**
42
* Returns a new multibinder that collects instances of type in a Set
43
* that is itself bound with annotationType.
44
*/
45
public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type, Class<? extends Annotation> annotationType);
46
47
/**
48
* Returns a new multibinder that collects instances of the key's type in a Set
49
* that is itself bound with the annotation (if any) of the key.
50
*/
51
public static <T> Multibinder<T> newSetBinder(Binder binder, Key<T> key);
52
```
53
54
### Element Binding
55
56
Add elements to the Set collection.
57
58
```java { .api }
59
/**
60
* Returns a binding builder used to add a new element in the set. Each bound element
61
* must have a distinct value. Bound providers will be evaluated each time the set is injected.
62
*
63
* It is an error to call this method without also calling one of the to methods on the
64
* returned binding builder. Scoping elements independently is supported.
65
*/
66
public LinkedBindingBuilder<T> addBinding();
67
```
68
69
### Duplicate Handling
70
71
Configure how duplicate elements are handled.
72
73
```java { .api }
74
/**
75
* Configures the bound set to silently discard duplicate elements. When multiple equal
76
* values are bound, the one that gets included is arbitrary. When multiple modules
77
* contribute elements to the set, this configuration option impacts all of them.
78
*/
79
public Multibinder<T> permitDuplicates();
80
```
81
82
### Provider Method Support
83
84
Contribute elements using provider methods with the @ProvidesIntoSet annotation.
85
86
```java { .api }
87
/**
88
* Annotates methods of a Module to add items to a Multibinder. The method's return
89
* type and binding annotation determines what Set this will contribute to.
90
*/
91
@Target(METHOD)
92
@Retention(RUNTIME)
93
public @interface ProvidesIntoSet {}
94
```
95
96
**Usage Examples:**
97
98
**Basic Set Binding:**
99
100
```java
101
public class SnacksModule extends AbstractModule {
102
@Override
103
protected void configure() {
104
Multibinder<Snack> multibinder = Multibinder.newSetBinder(binder(), Snack.class);
105
multibinder.addBinding().toInstance(new Twix());
106
multibinder.addBinding().toProvider(SnickersProvider.class);
107
multibinder.addBinding().to(Skittles.class);
108
}
109
}
110
111
// Injection
112
@Inject
113
public SnackMachine(Set<Snack> snacks) {
114
this.snacks = snacks; // Contains Twix, Snickers, Skittles
115
}
116
```
117
118
**Annotated Set Binding:**
119
120
```java
121
public class WebServicesModule extends AbstractModule {
122
@Override
123
protected void configure() {
124
Multibinder<RequestHandler> multibinder = Multibinder.newSetBinder(
125
binder(), RequestHandler.class, Names.named("web"));
126
multibinder.addBinding().to(UserRequestHandler.class);
127
multibinder.addBinding().to(OrderRequestHandler.class);
128
}
129
}
130
131
// Injection
132
@Inject
133
public WebServer(@Named("web") Set<RequestHandler> handlers) {
134
this.handlers = handlers;
135
}
136
```
137
138
**Provider Method Binding:**
139
140
```java
141
public class ServicesModule extends AbstractModule {
142
@ProvidesIntoSet
143
RequestHandler provideUserHandler(UserService userService) {
144
return new UserRequestHandler(userService);
145
}
146
147
@ProvidesIntoSet
148
@Named("web")
149
RequestHandler provideWebHandler() {
150
return new WebRequestHandler();
151
}
152
}
153
```
154
155
**Provider Collection Injection:**
156
157
```java
158
// Can also inject Collection<Provider<T>> for lazy evaluation
159
@Inject
160
public SnackMachine(Collection<Provider<Snack>> snackProviders) {
161
this.snackProviders = snackProviders;
162
}
163
```
164
165
**Multiple Modules Contributing:**
166
167
```java
168
// CandyModule
169
public class CandyModule extends AbstractModule {
170
@Override
171
protected void configure() {
172
Multibinder<Snack> multibinder = Multibinder.newSetBinder(binder(), Snack.class);
173
multibinder.addBinding().to(Chocolate.class);
174
multibinder.addBinding().to(Gummies.class);
175
}
176
}
177
178
// ChipsModule
179
public class ChipsModule extends AbstractModule {
180
@Override
181
protected void configure() {
182
Multibinder<Snack> multibinder = Multibinder.newSetBinder(binder(), Snack.class);
183
multibinder.addBinding().to(Doritos.class);
184
multibinder.addBinding().to(Cheetos.class);
185
}
186
}
187
188
// Final injected Set contains elements from both modules
189
```
190
191
**Duplicate Handling:**
192
193
```java
194
public class ConfigModule extends AbstractModule {
195
@Override
196
protected void configure() {
197
Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class)
198
.permitDuplicates(); // Allow duplicate values
199
multibinder.addBinding().toInstance("config1");
200
multibinder.addBinding().toInstance("config1"); // Would normally fail without permitDuplicates()
201
}
202
}
203
```
204
205
## Key Features
206
207
- **Element Uniqueness**: By default, elements must be distinct or injection will fail
208
- **Iteration Order**: Set iteration order is consistent with binding order within a module
209
- **Multi-Module Support**: Multiple modules can contribute to the same Set
210
- **Provider Support**: Can inject `Collection<Provider<T>>` for lazy evaluation
211
- **Scoping**: Individual elements can be scoped independently
212
- **Annotation Support**: Different Sets of same type can be created using binding annotations