Zero-cost, compile-time, type-safe dependency injection library providing macros for automatic instance creation in Scala applications
—
Context-free wiring with autowire creates instances using explicitly provided dependencies, without relying on the surrounding context. This approach is only available in Scala 3 and provides maximum flexibility in dependency specification.
Creates an instance of type T using provided dependencies. Missing dependencies are automatically created using public constructors or companion object apply methods.
inline def autowire[T](inline dependencies: Any*): TParameters:
dependencies: Any* - Variable number of dependency specificationsReturns: Instance of type T with all dependencies wired
Dependency Types: Each dependency parameter can be:
classOf[SomeType] to instantiate the class for dependency types it implementsimport com.softwaremill.macwire.*
class DatabaseAccess()
class SecurityFilter()
class UserFinder(databaseAccess: DatabaseAccess, securityFilter: SecurityFilter)
class UserStatusReader(userFinder: UserFinder)
// Creates all dependencies automatically
val userStatusReader = autowire[UserStatusReader]()Generates equivalent code:
val userStatusReader = {
val wiredDatabaseAccess = new DatabaseAccess()
val wiredSecurityFilter = new SecurityFilter()
val wiredUserFinder = new UserFinder(wiredDatabaseAccess, wiredSecurityFilter)
val wiredUserStatusReader = new UserStatusReader(wiredUserFinder)
wiredUserStatusReader
}import java.io.Closeable
class DataSource(jdbcConn: String) extends Closeable { def close() = () }
class DatabaseAccess(ds: DataSource)
class UserFinder(databaseAccess: DatabaseAccess)
// Provide pre-configured DataSource instance
val dataSource = new DataSource("jdbc:postgresql://localhost/mydb")
val userFinder = autowire[UserFinder](dataSource)class ConfiguredService(config: Config)
// Use function to create dependency
val createService = () => new ConfiguredService(loadConfig())
val someService = autowire[SomeServiceUsingConfiguredService](createService)trait Logger
class ConsoleLogger extends Logger
class FileLogger extends Logger
class Service(logger: Logger)
// Specify which Logger implementation to use
val service = autowire[Service](classOf[ConsoleLogger])class EmailService(smtpHost: String, port: Int)
class NotificationService(emailService: EmailService, logger: Logger)
class UserService(notificationService: NotificationService)
class AppConfig {
val smtpHost = "smtp.example.com"
val smtpPort = 587
val logger = new ConsoleLogger()
}
val appConfig = new AppConfig()
// Combine multiple dependency sources
val userService = autowire[UserService](
appConfig.smtpHost,
appConfig.smtpPort,
appConfig.logger
)autowire are checked firstapply methodsInstall with Tessl CLI
npx tessl i tessl/maven-com-softwaremill-macwire--macros