En la biblioteca de Injekt para Kotlin, ¿cómo creo ámbitos locales, como para cada actividad de Android?

En la documentation de Injekt en Github, dice que existen ámbitos, pero no está claro cómo puedo usarlos para crear un scope local para cada actividad de Android, que tienen sus propias fábricas e instancias, pero también pueden usar algunas de un scope principal.

La variable Injekt parece ser un ámbito global, y veo InjektScope e InjektScopeMain pero no hay ejemplos de cómo usarlos ni cómo se vinculan con los ámbitos principales. La única forma que veo es crear instancias de InjektScope separadas y llamarlas, O llamar a Injekt como un scope global. Esto funciona, pero es torpe.

No hay una forma obvia de vincular, anidar, delegar o henetworkingar.

¿Esto es compatible, y si es así cómo?

Nota: esta pregunta fue escrita y respondida intencionalmente por el autor ( Preguntas de respuesta automática ), de modo que las respuestas idiomáticas a los temas comúnmente solicitados de Injekt + Kotlin están presentes en SO. Otras respuestas también son bienvenidas, ¡hay otros styles de cómo hacer esto! Divulgación, soy el autor de la biblioteca Injekt.

ACTUALIZACIÓN: Esto ahora está documentado en Injekt README

Es apoyado por la delegación de fábricas entre los ámbitos. Primero, algunos antecedentes:

Injekt permite el scope manual de las instancias en loggings de Injekt separados. El logging global, disponible a través de la variable Injekt , es solo un scope creado previamente para usted. También puedes crear nuevos:

 val myLocalScope: InjektScope = InjektScope(DefaultRegistrar()) 

Esto crea un ámbito independiente que no tiene ninguna relación con el mundo o con otros.

Pero luego puede vincular ámbitos creando fábricas en el nuevo ámbito que delegue parte de la creación de instancias en otro ámbito. Por ejemplo, el myLocalScope mencionado anteriormente podría delegar algunas de las fábricas al scope global de Injekt :

 // delegate some factories to global Injekt instance myLocalScope.addSingletonFactory { Injekt.get<SomeSingletonClass>() } myLocalScope.addFactory { Injekt.get<SomeMultiValueClass>() } 

Al delegar fábricas como esta, cualquier instancia multivalor no será almacenada en caching por ningún scope, ya que esas fábricas crean nuevas instancias en cada llamada. Para los singletons y las fábricas con key, los objects se almacenan en caching y existirá una reference a esos objects tanto en el ámbito local como en el delegado para cualquier instancia solicitada durante su ciclo de vida.

También puede usar múltiples ámbitos de forma independiente sin vincular ni delegar. Obtener algunas instancias desde un ámbito local, otras desde el global. Pero debe usar cada ámbito de forma independiente y tener cuidado de utilizar accidentalmente la variable global Injekt cuando no esté previsto.

Si tiene fábricas comunes necesarias en ámbitos locales, puede crear fácilmente un descendiente de InjektScope que las registre durante su construcción.

 class MyActivityScope: InjektScope(DefaultRegistrar()) { init { // override with local value addSingletonFactory { SomeSingletonClass() } // import other registrations from defined modules importModule(OtherModuleWithPrepackagedInjektions) // delegate to global scope: addSingletonFactory { Injekt.get<SomeOtherSingleton>() } } } // then in each place you want a local scope val localScope = MyActivityScope() // later use the scope val singly: SomeSingletonClass = localScope.get() val other: SomeOtherSingleton = localScope.get() 

O usando el mismo model que InjektMain cree un descendiente de InjektScopedMain que anule la function de fun InjektRegistrar.registerInjectables() { ... } , si prefiere ser consistente con los modules. Por ejemplo:

 class MyActivityModule: InjektScopedMain(InjektScope(DefaultRegistrar())) { override fun InjektRegistrar.registerInjectables() { // override with local value addSingletonFactory { NotLazy("Fnetworkingdy") } // import other registrations from defined modules importModule(OtherModuleWithPrepackagedInjektions) // delegate to global scope: addSingletonFactory { Injekt.get<SomeOtherSingleton>() } } } // then in each place you want a local scope val localScope = MyActivityModule().scope 

Y aún puede usar properties delegadas, siempre que el scope se declare antes de su uso en el delegado:

 val myProp: SomeClass by localScope.injectValue() 

Puede usar la class base LocalScoped para tener versiones locales de injectValue() e injectLazy() para hacerlo más conveniente cuando se inyectan miembros (vea el código para LocalScoped ). De esta forma, su syntax se mantiene constante (ver ejemplo en las testings ).

Para borrar un scope local, suelte su reference al scope y se saveá todo. No hay un método explícito claro.

Para get un enlace / delegación / inheritance más avanzado y más automático, consulte Injekt Github Issue # 31 y brinde comentarios sobre esta posible function futura.

Para el caso de uso de tener otras classs, henetworkingar el mismo ámbito local cuando se inyectan en la class que declara el ámbito local, consulte Injekt Github Issue # 32

  • Tenga la security de que multiparte es nulo en el controller de descanso
  • Usando Anko SQLLite, ¿cuál es la mejor manera de verificar si existe una database?
  • Hibernate @OneToMany join table arroja StackOverflowException
  • Adaptador de enlace de Android no funciona para CustomView
  • Forma idiomática de volver si no nulo en Kotlin
  • error al usar 'npm start' con la aplicación creada por 'create-react-kotlin-app'
  • error: los generics no son compatibles en -source 1.3 al comstackr el código de Java con Kotlin
  • Sobrecarga de extensión de Kotlin para Android
  • Convertir matriz en list en Kotlin
  • Cómo colocar el dialog en la parte inferior
  • Kotlin - IllegalArgumentException en método anulado