or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdmap-binding.mdoptional-binding.mdset-binding.md

set-binding.mddocs/

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