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);
}
}
}