Инъекция через фабрику, когда у конструктора есть параметры в зубочистке - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть класс, который я хочу внедрить, у которого есть конструктор, который получает один параметр (Context).

Я бы обычно связывал его с экземпляром, но у этого класса есть зависимости JNI, и я не могу создать его экземпляр с помощью Robolectric, что не позволяет мне тестировать часть приложения, когда модуль настроен.

Я установил его как привязку к классу и аннотировал целевой класс как синглтон, а также конструктор как инъекцию, но он не создает фабрику для него.

Я буду рад предоставить собственную фабрику, но я не могу найти ничего об этом в документации.

Это часть, когда я делаю переплет:

val module = Module()        
module.bind(Interface::class.java).to(InterfaceImpl::class.java)
scope.installModules(module)

И вот как я настроил класс:

@Singleton
class InterfaceImpl : Interface {

   @Inject
   constructor(applicationContext: Context) {
      [...]
   }
}

Просто чтобы прояснить, если я использую toInstance, когда выполняю привязку, она работает.

val module = Module()        
module.bind(Interface::class.java).toInstance(InterfaceImpl(context))
scope.installModules(module)

Как я могу заставить инжектор работать, чтобы связать его с классом?

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018
SomeModule(getContext())

bind(Context::class.java).toInstance(context)
bind(InterfaceImpl::class.java).singletonInScope()
bind(Interface::class.java).toProvider(InterfaceProvider::class.java).providesSingletonInScope()

class InterfaceProvider @Inject constructor(private val impl: InterfaceImpl) : Provider<Interface> {
        override fun get(): Interface{
            return impl
        }}
0 голосов
/ 17 сентября 2018

Я нашел способ.В документации немного не хватает.

Я могу связать ее с помощью экземпляра провайдера:

val module = Module()
module.bind(Interface::class.java).toProviderInstance(InterfaceProvider(this))
scope.installModules(module)

И затем получить интерфейсный провайдер, например:

class InterfaceProvider (private val context: Context): Provider<Interface> {

    companion object {
        private var instance: Interface? = null
    }

    override fun get(): Interface {
        if (instance == null) {
            instance = InterfaceImpl(context)
        }
        return instance!!
    }
}

Или веще проще, используя лямбды в Kotlin:

val module = Module()
module.bind(Interface::class.java).toProviderInstance {
    InterfaceImpl(this)
}.providesSingletonInScope()
...