una tienda sistema que libros jfc fuente ejercicio consiste codigo biblioteca java android dagger-2

java - tienda - Daga 2: proporcione la misma instancia entre varios componentes con el mismo alcance en diferentes módulos de biblioteca



swing java (1)

Tengo una biblioteca principal de Android en la que estoy definiendo un anuncio de CoreComponent utilizando el alcance @Singleton para inyectar instancias de clases proporcionadas por un CoreModule.

@Singleton @Component(modules = {CoreModule.class}) public interface CoreComponent { void inject(SomeClass target); } @Module public class CodeModule { @Singleton @Provides CoreRepository provideCoreRepository() { return new CoreRepositoryImpl(); } }

Me gustaría acceder a las mismas instancias de @Singleton desde otra biblioteca de Android que depende de la biblioteca principal y utiliza otro componente.

@Singleton @FooScope @Component(modules = {CoreModule.class, FooModule.class}) public interface FooComponent { void inject(SomeActivity target); } public class FooActivity extends AppCompatActivity { @Inject public CoreRepository repo; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { injectDependencies(); super.onCreate(savedInstanceState); } [...] }

El código anterior se compila, pero el ámbito de @Singleton es "local" al Componente. En otras palabras, hay dos instancias singleton, una para el CoreComponent y otra para el FooComponent.

Android Application ├── Foo Library | └── Core Library ├── Bar Library | └── Core Library · · · └── Core Library

Creo que la mejor solución debería ser usar un Subcomponente pero, desafortunadamente, no parece posible porque la Biblioteca Central no tiene visibilidad de las otras bibliotecas.

¿Hay otra manera de compartir con Dagger la misma instancia de una clase entre componentes si la clase se anota con el mismo Ámbito?


Elimine los sitios de inyección de su CoreComponent ; ahora tiene la única función de exponer el enlace de CoreRepository a sus componentes dependientes:

@Singleton @Component(modules = {CoreModule.class}) public interface CoreComponent { CoreRepository coreRepository(); }

Cree una referencia a este componente de ámbito singleton dentro de su aplicación:

public class MyApplication extends Application { private final CoreComponent coreComponent; @Override public void onCreate() { super.onCreate(); coreComponent = DaggerCoreComponent .coreModule(new CoreModule()) .build(); } public static CoreComponent getCoreComponent(Context context) { return ((MyApplication) context.getApplicationContext()).coreComponent; } }

Crear un nuevo ámbito más estrecho:

@Scope @Retention(RetentionPolicy.RUNTIME) public @interface PerActivity {}

Cree un nuevo componente que haga un seguimiento de este alcance completo con los sitios de inyección que desea:

@PerActivity @Component(dependencies = {CoreComponent.class}) public interface ActivityComponent { void inject(FooActivity activity); void inject(BarActivity activity); }

Cuando acceda a este componente de ámbito de actividad en el sitio de inyección, deberá proporcionar la instancia de CoreComponent al constructor. Ahora puedes inyectar en tu Activity

public class FooActivity extends AppCompatActivity { @Inject public CoreRepository repo; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); CoreComponent coreComponent = MyApplication.getCoreComponent(this); DaggerActivityComponent.builder() .coreComponent(coreComponent) .build() .inject(this); } } }