我有一个 Core Android 库,我在其中定义一个 CoreComponent 广告,使用 @Singleton 范围来注入(inject) CoreModule 提供的类的实例。
@Singleton
@Component(modules = {CoreModule.class})
public interface CoreComponent {
void inject(SomeClass target);
}
@Module
public class CoreModule {
@Singleton
@Provides
CoreRepository provideCoreRepository() {
return new CoreRepositoryImpl();
}
}
我想从另一个依赖于核心库并使用另一个组件的 Android 库访问相同的 @Singleton 实例。
@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);
}
[...]
}
上面的代码可以构建,但 @Singleton 范围是组件的“本地”。换句话说,有两个单例实例,一个用于 CoreComponent,一个用于 FooComponent。
Android Application
├── Foo Library
| └── Core Library
├── Bar Library
| └── Core Library
·
·
·
└── Core Library
我认为最好的解决方案应该是使用子组件,但不幸的是,这似乎不可能,因为核心库无法看到其他库。
如果类使用相同的 Scope 注释,是否有另一种方法可以在组件之间与 Dagger 共享一个类的相同实例?
最佳答案
从您的 CoreComponent
中删除注入(inject)站点 - 它现在具有将 CoreRepository
的绑定(bind)暴露给其依赖组件的唯一功能:
@Singleton
@Component(modules = {CoreModule.class})
public interface CoreComponent {
CoreRepository coreRepository();
}
在您的应用程序中创建对这个单例范围组件的引用:
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;
}
}
创建一个新的更窄的范围:
@Scope
@Retention(RetentionPolicy.RUNTIME) public @interface PerActivity {}
创建一个跟踪此范围的新组件,其中包含您想要的注入(inject)站点:
@PerActivity
@Component(dependencies = {CoreComponent.class})
public interface ActivityComponent {
void inject(FooActivity activity);
void inject(BarActivity activity);
}
当您在注入(inject)站点中访问此 Activity 范围的组件时,您需要向构建器提供 CoreComponent
的实例。现在你可以注入(inject)你的 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);
}
}
}
关于java - Dagger 2 : Provide same instance between multiple Component with same Scope on different library modules,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40745279/