Dagger 2, módulos de biblioteca y @Singleton
Estoy tratando de usar Dagger 2 en un proyecto de Android que tiene varios módulos de la biblioteca de Android y me gustaría ser capaz de proporcionar instancias singleton escoped de clases de estos módulos.
Actualmente soy capaz de definir los componentes dentro de los módulos de la biblioteca e inyectar las instancias en el módulo de la aplicación principal.
- @Injects después de @Produces?
- Inyectar base de datos en un ContentProvider con daga
- Componente Dagger2 con más de una dependencia
- Dagger 2, a veces en la compilación me sale "no se puede encontrar la clase de símbolo DaggerApplicationComponent"
- Dagger2 Component (un-scoped) no puede depender de los componentes del ámbito - Error
Lo que no soy capaz de hacer es proporcionar una instancia como singleton.
La estructura del proyecto es la siguiente:
Project ├── app ├── library1 · · · └── libraryN
En las bibliotecas estoy definiendo los componentes de esta manera:
@Component public interface LibraryComponent { // Provide instances of MyManager to MainComponent: MyManager getMyManager(); }
Y MyManager se ve así:
public class MyManager { private static final String TAG = "MyManager"; @Inject public MyManager() { Log.d(TAG, "Creating MyManager"); } }
En la aplicación principal estoy definiendo mi componente de esta manera:
@ApplicationScope @Component(dependencies = {LibraryComponent.class, Library2Component.class}) public interface MainComponent { void inject(MainActivity target); }
Esta es la clase de aplicación:
public class App extends Application { private MainComponent component; @Override public void onCreate() { super.onCreate(); component = DaggerMainComponent.builder() .libraryComponent(DaggerLibraryComponent.create()) .library2Component(DaggerLibrary2Component.create()) .build(); } public MainComponent getComponent() { return component; } }
Si agrego un ámbito a sólo un componente de biblioteca, entonces puedo proporcionar al administrador como singleton. Pero si trato de hacer lo mismo con una biblioteca más, estoy recibiendo el error:
@com.codeblast.dagger2lib.ApplicationScope com.codeblast.dagger2lib.MainComponent depends on more than one scoped component: @Component(dependencies = {LibraryComponent.class, Library2Component.class}) ^ @com.codeblast.library.LibraryScope com.codeblast.library.LibraryComponent @com.codeblast.library2.Library2Scope com.codeblast.library2.Library2Component
Una vez más, lo que me gustaría lograr es simplemente inyectar en mi proyecto de aplicación principal Singleton escoped instancias de algunos administradores proporcionados por los proyectos de la Biblioteca .
- Alcance de la actividad Dagger2, ¿cuántos módulos / componentes necesito?
- ¿Es posible a los miembros de @Inject (proporcionados a través de @Provides), que contienen un Contexto de Actividad de la Actividad Base
- Dagger2 - nulo en lugar del objeto inyectado
- Dagger2 dagger.android. * Las clases no existen
- Java.lang.NoClassDefFound usando Dagger 2 para Android 4
- Adición de clases sin actividad a Dagger 2 Graph Android
- Escopetas en Dagger 2
- Dagger2: Error cuando dos componentes tienen la misma firma de método de inyección
Como sugirió @EpicPandaForce, el uso de Dagger Modules en lugar de Components resolvió mi problema .
A continuación, los cambios necesarios que tuve que hacer.
El primero es borrar la biblioteca Componentes y crear módulos de biblioteca:
@Module public class LibraryModule { @Singleton @Provides MyManager provideMyManager(MyUtility myUtility) { return new MyManager(myUtility); } }
Más que especificar esos Módulos en el Componente de la Aplicación, en lugar de las dependencias del Componente:
@Singleton @Component(modules = {LibraryModule.class, Library2Module.class}) public interface MainComponent { void inject(MainActivity target); }
Y eso es todo, con este código, las clases Manager, anotadas con el alcance de @Singleton, se instancian correctamente una sola vez.
Intente unificar los componentes de la biblioteca bajo un solo componente (por ejemplo: AllLibrariesComponent) y, a continuación, deje que su MainComponent tenga como dependencia sólo AllLibrariesComponent.
Biblioteca1:
@Component @Singleton public interface LibraryComponent { // Provide instances of MyManager to MainComponent: MyManager getMyManager(); } @Singleton public class MyManager { private static final String TAG = "MyManager"; @Inject public MyManager() { Log.d(TAG, "*** Creating MyManager 1 ***"); } }
Library2:
@Singleton @Component public interface Library2Component { // Provide instances of MyManager to MainComponent: MyManager2 getManager2(); } @Singleton public class MyManager2 { private static final String TAG = "MyManager"; @Inject public MyManager2() { Log.d(TAG, "*** Creating MyManager 2 *** "); } }
App:
@Singleton @Component public interface AllLibrariesComponent extends Library2Component, LibraryComponent{ } @PerApplication @Component(dependencies = AllLibrariesComponent.class) public interface MainComponent { void inject(MainActivity activity); } // .... // and the instantication in your application class: mainComponent = DaggerMainComponent.builder() .allLibrariesComponent(DaggerAllLibrariesComponent.create()) .build();
- WidgetProvider Los extras de intención enviados con el botón de clic no se encuentran en onReceive
- Uso del sensor magnético