aplicación de intercambio de tiempo de ejecución para la Daga proporciona la dependencia [duplicado] -- dagger-2 camp Relacionados El problema

Runtime swap implementation for Dagger provided dependency [duplicate]


1
vote

problema

Español
Esta pregunta ya tiene respuestas aquí :
¿Cómo le digo Daga 2 que la implementación para crear una instancia basado en X? (3 respuestas)
cerrado Hace 4 años
.

Uso Dagger 2, I tiene un objeto de dominio que proporciono a los presentadores. Ese objeto de dominio tiene una dependencia en un repositorio. Eso repositorio tiene dos implementaciones, pero ambos implementar la misma interfaz. Tengo que ser capaz de daga configuración alguna manera de cambiar entre las dos implementaciones del repositorio en tiempo de ejecución en base a un usuario seleccionar una opción "Modo Demo".

Así que tengo el siguiente objeto de dominio:

  public class SomeAwesomeBusinessLogic {      Repository repository;      @Inject     public SomeAwesomeBusinessLogic(Repository repository) {         this.repository = repository;     }     //awesome stuff goin down }   

Y los dos repositorios:

  public RemoteRepository implements Repository {      @Inject     public RemoteRepository() {         //setup     } }  public DemoRepository implements Repository {      @Inject     public DemoRepository() {         //setup     } }   

¿Alguna idea sobre cómo estructurar mis módulos y componentes para conseguir que esto funcione?

Original en ingles

Using Dagger 2, I have a domain object that I provide to presenters. That domain object has a dependency on a repository. That repository has two implementations, but both implement the same interface. I need to be able to setup dagger somehow to swap between the two implementations of the repository at runtime based on a user selecting a "Demo Mode" option.

So I have the following domain object:

public class SomeAwesomeBusinessLogic {      Repository repository;      @Inject     public SomeAwesomeBusinessLogic(Repository repository) {         this.repository = repository;     }     //awesome stuff goin down } 

And the two repositories:

public RemoteRepository implements Repository {      @Inject     public RemoteRepository() {         //setup     } }  public DemoRepository implements Repository {      @Inject     public DemoRepository() {         //setup     } } 

Any ideas on how to structure my modules and components to get this to work?

  

Lista de respuestas

0
 
vote

Un par de ideas vienen a mi cabeza. Dependiendo de cómo y cuándo quieres intercambiar esto. Una posibilidad es instanciar su módulo con una configuración. Puede ser un simple booleano:

  @Module public class RepositoryModule {   private final boolean isDemo;    public RepositoryModule(boolean isDemo) {     this.isDemo = isDemo;   }    @Provides   public Repository providesRepository() {     return isDemo? new DemoRepository() : new RemoteRepository();   }   // Other providers }   

No soy un fanático de este enfoque, pero se ajusta a su caso de uso. Creo que es bastante restrictivo y no permite una fácil mantenibilidad. Tal vez elegiría usar una fábrica y proporcionar la fábrica en lugar del repositorio.

  public interface RepositoryFactory {    Repository getRepository(Configuration configuration); }  public class RepositoryFactoryImpl implements RepositoryFactory {     @Inject    public RepositoryFactoryImpl() {}     // The implementation }  @Module public class RepositoryModule {   @Provides   public RepositoryFactory providesRepositoryFactory(             RepositoryFactoryImpl factory) {     return factory;   }   // Other providers }   

Configuration sería un pojo simple donde pueda especificar varios atributos para configurar su repo. Diga, por ejemplo:

  public class Configuration {    private final boolean isDemo;    // all the POJO stuff you need }   

Puede hacer que su objeto de dominio dependa de la fábrica:

  public class SomeAwesomeBusinessLogic {     private final RepositoryFactory repositoryFactory;     @Inject    public SomeAwesomeBusinessLogic(                 RepositoryFactory repositoryFactory) {       this.repositoryFactory = repositoryFactory;    }    //awesome stuff going down }   

Puede hacerlo repositoryFactory.getRepository(new Configuration(true/false)); en la lógica de su negocio.

Prefiero este enfoque porque es más fácil extenderse a nuevos tipos de repos. También puede probar si la lógica de fábrica es correcta. Nadie generalmente prueba los módulos de daga, por eso no estoy tan interesado en el primer enfoque.

Otra cosa buena es que este enfoque le permite mantener la misma instancia del módulo si existe la posibilidad de cambiar la configuración de la aplicación y cambiar de repente a un repo de demostración, proporcionando un objeto public class SomeAwesomeBusinessLogic { private final RepositoryFactory repositoryFactory; @Inject public SomeAwesomeBusinessLogic( RepositoryFactory repositoryFactory) { this.repositoryFactory = repositoryFactory; } //awesome stuff going down } 8 diferente a la fábrica.

Una tercera posibilidad puede ser productores . Sin embargo, esto realmente depende de su caso de uso y de cómo desea manejar este intercambio de dependencia de tiempo de ejecución. Encuentro que este enfoque sea bastante bueno, pero podría ser un poco excesivo.

Espero que esto ayude

 

A couple of ideas come to my head. Depending on how and when you want to exchange this. One possibility is to instantiate your module with a configuration. Can be a simple boolean:

@Module public class RepositoryModule {   private final boolean isDemo;    public RepositoryModule(boolean isDemo) {     this.isDemo = isDemo;   }    @Provides   public Repository providesRepository() {     return isDemo? new DemoRepository() : new RemoteRepository();   }   // Other providers } 

I'm not a fan of this approach, but it fits your use case. I believe it's quite restrictive and doesn't allow for easy maintainability. I would perhaps choose to use a factory and provide the factory instead of the repo itself.

public interface RepositoryFactory {    Repository getRepository(Configuration configuration); }  public class RepositoryFactoryImpl implements RepositoryFactory {     @Inject    public RepositoryFactoryImpl() {}     // The implementation }  @Module public class RepositoryModule {   @Provides   public RepositoryFactory providesRepositoryFactory(             RepositoryFactoryImpl factory) {     return factory;   }   // Other providers } 

Configuration would be a simple POJO where you can specify several attributes to configure your repo. Say for example:

public class Configuration {    private final boolean isDemo;    // all the POJO stuff you need } 

You can then make your domain object depend on the factory:

public class SomeAwesomeBusinessLogic {     private final RepositoryFactory repositoryFactory;     @Inject    public SomeAwesomeBusinessLogic(                 RepositoryFactory repositoryFactory) {       this.repositoryFactory = repositoryFactory;    }    //awesome stuff going down } 

You can then do repositoryFactory.getRepository(new Configuration(true/false)); in your business logic.

I prefer this approach because it's easier to extend to new types of repos. You can also test if the factory logic is correct. No one usually tests dagger modules, that's why I'm not so keen on the first approach.

Another good thing is that this approach allows you to keep the same module instance if there's a possibility to change the app's configuration and suddenly change to a demo repo, by providing a different Configuration object to the factory.

A third possibility might be Producers. However, this really depends on your use case and how you want to handle this runtime dependency exchange. I find this approach quite good, but it might be a bit overkill.

Hope this helps

 
 

Relacionados problema

2  Hilt ClassCastException: ViewComponentManager $ FragmentContextWrapper no se puede emitir a AppCompativity  ( Hilt classcastexception viewcomponentmanagerfragmentcontextwrapper cannot be c ) 
Tengo este código donde muestro fragmento de diálogo al hacer clic en un elemento de visualizador en el adaptador static void Main(string[] args) { for...

9  Dagger2 Non-@ Nullable @Provides Method  ( Dagger2 non nullable provides method ) 
Estoy al comienzo de usar Daga a mis proyectos. He hecho estos módulos: @Module public class FirebaseModule { @Provides @Singleton public FirebaseUser pro...

4  ¿Qué sucede si no pongo el componente Dagger 2 a NULL en la actividad ONDESTROY ()?  ( What happens if i dont set dagger 2 component to null in activity ondestroy ) 
Veo que si se instanca un componente 2 Dagger 2 en una actividad, luego se nulla más tarde en el método true or false 8 como visto AQUÍ . public class M...

5  Android utilizando un solo contexto para múltiples módulos Dagger2  ( Android using single context for multiple dagger2 modules ) 
Soy Newbie para usar Dagger2 en Android. Crea alguna clase como módulo de daga que están usando context , no puedo fusionar, combinar o usar un solo contex...

1  Resolver la dependencia llamada con Dagger 2 después de que se inicialice la clase  ( Resolve named dependency with dagger 2 after the class is initialized ) 
Estoy usando Dagger 2 para la gestión de la dependencia de mi solicitud de Java. Tengo la siguiente estructura: <input onclick="InputComputerName" class=...

0  Android Kotlin Dagger2 proporciona GSE: Parámetro especificado como Non-Null es nulo  ( Android kotlin dagger2 provide gson parameter specified as non null is null ) 
Quiero proporcionar una sola instancia gís, por lo que le proporciono en mi Modulódulo, cuando creo una API de retrofit, GSON no es nula, pero cuando uso inst...

2  ERROR: (24, 0) No se pudo encontrar el método AnnotationProcessor () para argumentos [com.google.dagger: Dagger-Compiler: 2.10]  ( Error24 0 could not find method annotationprocessor for arguments com goo ) 
Intento construir un módulo: API en Android Studio 3, Gradle 4.1, Android Studio Plugin 3.0.0, usando Dagger 2 así que mi build.grade es: apply plugin: '...

17  Daga 2: ¿Qué hace @module (incluye =) hacer?  ( Dagger 2 what does moduleincludes do ) 
Estoy trabajando en un proyecto y estoy tratando de hacerlo lo más modular posible. Estoy tratando de usar la anotación @module (incluye = {{}) para lograr ...

1  @Propide Methods en Subcomponente con AndroidInjector y Kotlin  ( Provides methods in subcomponent with androidinjector and kotlin ) 
Estoy usando el Dagger2 AndroidInjector y Kotlin. Tengo un subcomponente con su módulo definido de esta manera: @Subcomponent(modules = arrayOf( UI...

1  Dagger2 - Componente Hold como objeto estático en aplicación  ( Dagger2 component hold as a static object in application ) 
En mi clase Application , tengo la daga de My Singleton Component como un objeto estático y alcancelo a través de su método estático de Getter. public c...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos