Я хотел бы создать настраиваемый модуль, который будет связывать несколько разных вещей @Named.Приложения / инъекции, которые используют модуль, будут знать @Name заранее, но сам модуль не будет знать, пока не будет создан его экземпляр во время выполнения.
Я использую kotlin в моем примере кода, но рад за javaответы.
Не удается скомпилировать, поскольку все аннотации @Named должны ссылаться на константные строки, а не на переменные времени выполнения (An annotation argument must be a compile-time constant
):
class DbModule(val configPath: String) : KotlinModule() {
@Provides
@Named(configPath) // <-- can't do this
fun provideDbConfig(loader: ConfigLoader): DbConfig {
// note ConfigLoader is separately bound,
// but a needed depenency of DbConfig
return DbConfig(loader, configPath)
}
@Provides
@Named(configPath) // <-- can't do this
fun provideDataSource(
@Named(configPath) // <-- can't do this
dbConfig: DbConfig): DataSource
{
return dbConfig.dataSource
}
}
Я могу получить привязку DbConfigчтобы работать, добавив провайдера:
private class ConfigProvider
@Inject constructor(
val loader: ConfigLoader,
@Named("configPath") val configPath: String
) : Provider<DbConfig> {
override fun get(): DbConfig {
return DbConfig(loader, configPath)
}
}
class DbModule(val configPath: String) : KotlinModule() {
override configure() {
bindConstant().annotatedWith(Names.named("configPath"))
.to(configPath)
bind<DbConfig>().annotatedWith(Names.named(configPath))
.toProvider(ConfigProvider::class.java)
}
}
Но я не уверен, как получить Provider<DataSource>
, который будет иметь правильный configPath
аннотированный DbConfig()
, доступный для него, чтобы он мог получитьDataSource
из конфига?Я мог бы иметь DataSourceProvider
, который создает свою собственную DbConfig(configPath)
точно так же, как ConfigProvider
, но кажется предпочтительным иметь guice для создания dbconfig через ConfigProvider
и использовать его в DataSourceProvider
?
В конце этого я хотел бы иметь возможность ввести следующее:
class BusinessObject1
@Inject constructor(
@Named("secondaryDb") val dbConfig: DbConfig
)
class BusinessObject2
@Inject constructor(
@Named("secondaryDb") val dataSource: DataSource
)
Предполагая, что эти объекты создаются инжектором:
Guice.createInjector(DbModule("secondaryDb"))
(также обратите внимание, что приведенный выше код не позволит создавать как DbModule("secondaryDb")
, так и DbModule("tertiaryDb")
, но это можно решить с помощью частных модулей, которые я оставил, чтобы избежать дополнительной сложности)