or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assisted-injection.mdcomponent-framework.mdindex.mdmodule-system.mdmultibindings.mdutility-types.md

assisted-injection.mddocs/

0

# Assisted Injection

1

2

Assisted injection in Dagger enables the creation of objects that require both injected dependencies and runtime parameters. This pattern uses factory interfaces to create instances where some parameters are provided by Dagger's dependency injection and others are passed at runtime.

3

4

## Capabilities

5

6

### @AssistedInject Annotation

7

8

Annotates constructors that require assisted injection, mixing dependencies injected by Dagger with parameters provided at runtime.

9

10

```java { .api }

11

/**

12

* Annotates constructors for assisted injection (runtime parameter passing)

13

*/

14

@Target(ElementType.CONSTRUCTOR)

15

@Retention(RetentionPolicy.RUNTIME)

16

@interface AssistedInject {}

17

```

18

19

**Key Features:**

20

- Cannot be used with scoping annotations (not scoped)

21

- Requires a corresponding @AssistedFactory

22

- Some parameters are injected by Dagger, others marked with @Assisted

23

- Only one constructor per class can have @AssistedInject

24

25

**Usage Examples:**

26

27

```java

28

public class UserSession {

29

private final UserService userService; // Injected by Dagger

30

private final User user; // Passed at runtime

31

private final String sessionId; // Passed at runtime

32

33

@AssistedInject

34

public UserSession(

35

UserService userService, // Dagger-provided

36

@Assisted User user, // Runtime parameter

37

@Assisted String sessionId // Runtime parameter

38

) {

39

this.userService = userService;

40

this.user = user;

41

this.sessionId = sessionId;

42

}

43

}

44

```

45

46

### @AssistedFactory Annotation

47

48

Annotates factory interfaces or abstract classes that create instances with assisted injection. The factory provides a clean API for creating objects with mixed parameter sources.

49

50

```java { .api }

51

/**

52

* Annotates factory interfaces/abstract classes for creating assisted injection types

53

*/

54

@Target(ElementType.TYPE)

55

@Retention(RetentionPolicy.RUNTIME)

56

@interface AssistedFactory {}

57

```

58

59

**Requirements:**

60

- Must be abstract class or interface

61

- Exactly one abstract method

62

- Return type must match the assisted injection type

63

- Method parameters must match @Assisted parameters in constructor

64

65

**Usage Examples:**

66

67

```java

68

@AssistedFactory

69

public interface UserSessionFactory {

70

UserSession create(User user, String sessionId);

71

}

72

73

// Usage

74

public class LoginService {

75

private final UserSessionFactory sessionFactory;

76

77

@Inject

78

public LoginService(UserSessionFactory sessionFactory) {

79

this.sessionFactory = sessionFactory;

80

}

81

82

public UserSession login(String username, String password) {

83

User user = authenticateUser(username, password);

84

String sessionId = generateSessionId();

85

return sessionFactory.create(user, sessionId);

86

}

87

}

88

```

89

90

### @Assisted Annotation

91

92

Annotates constructor parameters that are passed at runtime rather than injected by Dagger. Each @Assisted parameter must have a corresponding parameter in the factory method.

93

94

```java { .api }

95

/**

96

* Annotates constructor parameters that are passed at runtime (not injected)

97

*/

98

@Target(ElementType.PARAMETER)

99

@Retention(RetentionPolicy.RUNTIME)

100

@interface Assisted {

101

/**

102

* Identifier for distinguishing parameters of the same type

103

*/

104

String value() default "";

105

}

106

```

107

108

**Key Features:**

109

- Each @Assisted parameter uniquely identified by identifier + type

110

- Factory method parameters must match constructor @Assisted parameters

111

- Parameters without @Assisted are provided by Dagger

112

- Identifier helps distinguish multiple parameters of the same type

113

114

**Usage Examples:**

115

116

```java

117

public class DatabaseConnection {

118

private final ConnectionPool pool; // Injected

119

private final String host; // Runtime parameter

120

private final int port; // Runtime parameter

121

private final String database; // Runtime parameter

122

123

@AssistedInject

124

public DatabaseConnection(

125

ConnectionPool pool,

126

@Assisted String host,

127

@Assisted int port,

128

@Assisted String database

129

) {

130

this.pool = pool;

131

this.host = host;

132

this.port = port;

133

this.database = database;

134

}

135

}

136

137

@AssistedFactory

138

public interface DatabaseConnectionFactory {

139

DatabaseConnection create(String host, int port, String database);

140

}

141

```

142

143

### Assisted Parameters with Identifiers

144

145

When multiple parameters have the same type, use identifiers to distinguish them:

146

147

```java

148

public class Rectangle {

149

private final Graphics graphics; // Injected

150

private final int width; // Runtime parameter

151

private final int height; // Runtime parameter

152

153

@AssistedInject

154

public Rectangle(

155

Graphics graphics,

156

@Assisted("width") int width,

157

@Assisted("height") int height

158

) {

159

this.graphics = graphics;

160

this.width = width;

161

this.height = height;

162

}

163

}

164

165

@AssistedFactory

166

public interface RectangleFactory {

167

// Parameters must match identifiers and types

168

Rectangle create(@Assisted("width") int width, @Assisted("height") int height);

169

}

170

```

171

172

### Generic Assisted Injection

173

174

Assisted injection works with generic types:

175

176

```java

177

public class Repository<T> {

178

private final DatabaseService databaseService; // Injected

179

private final Class<T> entityClass; // Runtime parameter

180

private final String tableName; // Runtime parameter

181

182

@AssistedInject

183

public Repository(

184

DatabaseService databaseService,

185

@Assisted Class<T> entityClass,

186

@Assisted String tableName

187

) {

188

this.databaseService = databaseService;

189

this.entityClass = entityClass;

190

this.tableName = tableName;

191

}

192

}

193

194

@AssistedFactory

195

public interface RepositoryFactory {

196

<T> Repository<T> create(Class<T> entityClass, String tableName);

197

}

198

199

// Usage

200

public class UserService {

201

private final Repository<User> userRepository;

202

203

@Inject

204

public UserService(RepositoryFactory repositoryFactory) {

205

this.userRepository = repositoryFactory.create(User.class, "users");

206

}

207

}

208

```

209

210

### Complex Assisted Injection Patterns

211

212

**Multiple Factories:**

213

```java

214

public class ReportGenerator {

215

@AssistedInject

216

public ReportGenerator(

217

ReportService reportService,

218

@Assisted ReportType type,

219

@Assisted DateRange dateRange,

220

@Assisted("format") String format

221

) { /* ... */ }

222

}

223

224

// Different factories for different use cases

225

@AssistedFactory

226

public interface DailyReportFactory {

227

ReportGenerator create(

228

ReportType type,

229

@Assisted("format") String format

230

);

231

}

232

233

@AssistedFactory

234

public interface CustomReportFactory {

235

ReportGenerator create(

236

ReportType type,

237

DateRange dateRange,

238

@Assisted("format") String format

239

);

240

}

241

```

242

243

**Factory with Nullable Parameters:**

244

```java

245

public class EmailSender {

246

@AssistedInject

247

public EmailSender(

248

EmailService emailService,

249

@Assisted String recipient,

250

@Assisted @Nullable String cc,

251

@Assisted @Nullable String bcc

252

) { /* ... */ }

253

}

254

255

@AssistedFactory

256

public interface EmailSenderFactory {

257

EmailSender create(

258

String recipient,

259

@Nullable String cc,

260

@Nullable String bcc

261

);

262

}

263

```

264

265

### Integration with Components

266

267

Assisted factories must be explicitly bound in components:

268

269

```java

270

@Module

271

public abstract class AssistedInjectModule {

272

// No explicit binding needed - Dagger generates the factory implementation

273

}

274

275

@Component(modules = AssistedInjectModule.class)

276

public interface ApplicationComponent {

277

UserSessionFactory userSessionFactory();

278

DatabaseConnectionFactory databaseConnectionFactory();

279

RepositoryFactory repositoryFactory();

280

}

281

```

282

283

### Assisted Injection Best Practices

284

285

**Clear Parameter Naming:**

286

```java

287

// Good: Clear parameter purposes

288

@AssistedInject

289

public FileProcessor(

290

Logger logger, // Injected

291

@Assisted("input") File inputFile, // Runtime

292

@Assisted("output") File outputFile // Runtime

293

) { /* ... */ }

294

295

// Avoid: Ambiguous parameters

296

@AssistedInject

297

public FileProcessor(

298

Logger logger,

299

@Assisted File file1,

300

@Assisted File file2

301

) { /* ... */ }

302

```

303

304

**Factory Interface Design:**

305

```java

306

// Good: Descriptive factory methods

307

@AssistedFactory

308

public interface HttpClientFactory {

309

HttpClient createWithTimeout(int timeoutSeconds);

310

HttpClient createWithAuth(String token, int timeoutSeconds);

311

}

312

313

// Avoid: Generic create method

314

@AssistedFactory

315

public interface HttpClientFactory {

316

HttpClient create(Object... params);

317

}

318

```

319

320

**Error Handling:**

321

```java

322

public class SafeAssistedInjection {

323

@AssistedInject

324

public SafeAssistedInjection(

325

Validator validator,

326

@Assisted String input

327

) {

328

// Validate runtime parameters

329

if (input == null || input.trim().isEmpty()) {

330

throw new IllegalArgumentException("Input cannot be null or empty");

331

}

332

this.validator = validator;

333

this.input = validator.validate(input);

334

}

335

}

336

```