0
# MacWire Macros
1
2
MacWire Macros is a zero-cost, compile-time, type-safe dependency injection library for Scala. It provides compile-time macros that generate instance creation code automatically while maintaining type safety and eliminating runtime overhead. The library supports multiple wiring strategies, from context-free dependency injection to context-dependent resolution using surrounding scope.
3
4
## Package Information
5
6
- **Package Name**: com.softwaremill.macwire:macros
7
- **Package Type**: Maven (Scala library)
8
- **Language**: Scala (2.12, 2.13, 3)
9
- **Installation**: `"com.softwaremill.macwire" %% "macros" % "2.6.6" % "provided"`
10
- **Util Module** (for dynamic instance access): `"com.softwaremill.macwire" %% "util" % "2.6.6"`
11
- **Platforms**: JVM, JavaScript (Scala.js), Native (Scala Native)
12
13
## Core Imports
14
15
```scala
16
import com.softwaremill.macwire.*
17
```
18
19
For Scala 2:
20
```scala
21
import com.softwaremill.macwire._
22
```
23
24
## Basic Usage
25
26
```scala
27
import com.softwaremill.macwire.*
28
29
// Define your classes
30
class DatabaseAccess()
31
class SecurityFilter()
32
class UserFinder(databaseAccess: DatabaseAccess, securityFilter: SecurityFilter)
33
class UserStatusReader(userFinder: UserFinder)
34
35
// Context-free wiring with autowire (Scala 3)
36
val userStatusReader = autowire[UserStatusReader]()
37
38
// Context-dependent wiring
39
trait UserModule {
40
lazy val databaseAccess = new DatabaseAccess()
41
lazy val securityFilter = new SecurityFilter()
42
lazy val userFinder = wire[UserFinder]
43
lazy val userStatusReader = wire[UserStatusReader]
44
}
45
```
46
47
## Architecture
48
49
MacWire operates through several key mechanisms:
50
51
- **Compile-Time Code Generation**: All wiring happens at compile time via Scala macros, generating plain `new` instance creation code
52
- **Type-Safe Resolution**: Uses Scala's type system to resolve dependencies, providing compile-time error detection
53
- **Multiple Wiring Strategies**: Context-free (`autowire`), context-dependent (`wire`), and recursive (`wireRec`) approaches
54
- **Factory Support**: Custom factory functions can be wired using `wireWith` family of functions
55
- **Set Collection**: Automatic collection of multiple instances of the same type using `wireSet`
56
57
## Capabilities
58
59
### Context-Free Wiring
60
61
Context-free dependency injection using explicitly provided dependencies. Creates instances without relying on surrounding scope.
62
63
```scala { .api }
64
// Scala 3 only
65
inline def autowire[T](inline dependencies: Any*): T
66
```
67
68
[Context-Free Wiring](./context-free-wiring.md)
69
70
### Context-Dependent Wiring
71
72
Creates instances using dependencies available in the surrounding context (trait/class/object scope).
73
74
```scala { .api }
75
// Basic wiring
76
def wire[T]: T
77
78
// Recursive wiring - creates missing dependencies automatically
79
def wireRec[T]: T
80
81
// Set collection - gathers all instances of type T
82
def wireSet[T]: Set[T]
83
```
84
85
[Context-Dependent Wiring](./context-dependent-wiring.md)
86
87
### Factory-Based Wiring
88
89
Wires dependencies for factory functions, supporting functions with up to 22 parameters.
90
91
```scala { .api }
92
def wireWith[RES](factory: () => RES): RES
93
def wireWith[A, RES](factory: (A) => RES): RES
94
def wireWith[A, B, RES](factory: (A, B) => RES): RES
95
// ... overloads for up to 22 parameters
96
```
97
98
[Factory-Based Wiring](./factory-based-wiring.md)
99
100
### Dynamic Instance Access
101
102
Creates dynamic instance lookup capabilities from object members. **Note:** Only fully implemented in Scala 2.
103
104
```scala { .api }
105
def wiredInModule(in: AnyRef): Wired // Scala 2 implementation only
106
```
107
108
[Dynamic Instance Access](./dynamic-instance-access.md)
109
110
## Types
111
112
```scala { .api }
113
// From util module - requires separate dependency
114
import com.softwaremill.macwire.Wired
115
```
116
117
## Error Handling
118
119
MacWire provides compile-time error detection for:
120
121
- **Missing Dependencies**: When required constructor parameters cannot be resolved
122
- **Ambiguous Dependencies**: When multiple instances of the same type are available in context-dependent wiring
123
- **Cyclic Dependencies**: When recursive dependencies create circular references
124
- **Unsupported Types**: When attempting to wire primitive types or unsupported type patterns
125
126
All errors are reported at compile time with descriptive messages indicating the specific issue and location.