java Dagger 2.11:使用@ContributesAndroidInjector时的本地单例
我使用@ContributesAndroidInjector注释(https://google.github.io/dagger/安卓.html)进行了一个有效的匕首设置
Component Application
/ \
Subcomponent DrawerActivity Subcomponent SubActivity
|
Subcomponent DrawerFragment
在SubActivity和DrawerActivity中,我使用的是同一个存储库实例,标记为@Singleton
@Singleton
@Component(modules = {
AndroidInjectionModule.class,
AppModule.class,
ActivityBuilderModule.class
})
public interface AppComponent {
@Component.Builder
interface Builder{
@BindsInstance Builder application(Application application);
AppComponent build();
}
void inject(App app);
}
@Module
public abstract class ActivityBuilderModule {
@PerActivity
@ContributesAndroidInjector(modules = {DrawerActivityModule.class,
FragmentBuilderModule.class})
abstract DrawerActivity bindDrawerActivity();
@PerActivity
@ContributesAndroidInjector(modules = {DrawerActivityModule.class})
abstract SubActivity bindSubActivity();
}
@Module
public abstract class FragmentBuilderModule {
@PerFragment
@ContributesAndroidInjector(modules = DrawerFragmentModule.class)
abstract DrawerFragment provideDrawerFragment();
}
@Singleton
public class Repository{
private SomeClass mSomeClass;
@Inject
public VehicleRepositoryImpl(SomeClass someClass) {
mSomeClass = someClass;
}
}
public class App extends Application implements HasActivityInjector{
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
}
AppComponent component = DaggerAppComponent.builder().application(this)
.build();
component.inject(this);
}
@Override
public AndroidInjector<Activity> activityInjector() {
return dispatchingAndroidInjector;
}
}
public class DrawerActivity extends AppCompatActivity implements HasSupportFragmentInjector{
@Inject
DispatchingAndroidInjector<Fragment> fragmentDispatchingAndroidInjector;
@Override
public AndroidInjector<Fragment> supportFragmentInjector() {
return fragmentDispatchingAndroidInjector;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
}
}
public class DrawerFragment extends Fragment {
@Inject
ViewModelFactory mViewModelFactory; //repository gets injected into factory
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
AndroidSupportInjection.inject(this);
super.onCreate(savedInstanceState);
}
}
public class SubActivity extends AppCompatActivity{
@Inject
Repository mRepository;
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
}
}
我现在需要添加一个用户管理。这需要后勤活动。我不希望存储库在LoginActivity中可用。因此,我想为DrawerActivity/Subactivity/DrawerFragment创建一个本地单例作用域“UserScope”
Component Application
/ \
@UserScope @LoginScope
Subcomponent DrawerActivity SubComponent LoginActivity
| \
Subcomponent DrawerFragment Subcomponent SubActivity
仍然使用新的@ContributesAndroidInjector注释如何实现这一点
我希望它能像这篇博文一样工作:http://frogermcs.github.io/building-userscope-with-dagger2/
# 1 楼答案
Application
(已经有了注释@Singleton
的默认作用域),Activity
,BroadcastReceiver
,Fragment
,Service
,ContentProvider
(我从DaggerApplication
中获取的这个列表)。所以,取决于它将基于什么对象,您将在该对象的生命周期内获得可重用的依赖关系(它将是它的本地单例,例如活动/片段)@ContributesAndroidInjector
来生成@Subcomponent
。这个子组件应该被限定范围,这就是为什么我们把@FragmentScope
(我们自己创建的注释)放在它上面。两个子片段将属于此子组件,这就是我们为子片段创建独立模块并通过向父片段子组件的modules
添加参数将其添加到生成的子组件中的原因李>我省略了一些细节,比如描述AppComponent和向其中添加AppBindingModule,以及演示如何使用AndroidSupportInjection进行注入。注入(这)是因为它超出了主题。但如果需要澄清,请在评论中自由提问
# 2 楼答案
我通过在回购协议中这样做解决了我的问题:
https://github.com/ragdroid/Dahaka
非常感谢它的贡献者
更新1:添加了代码示例
此图给出了代码示例的大致概念
代码示例(如果缺少某些内容,请在注释中告知我):
1。匕首设置
AppComponent是Dagger图的根:
绑定其子组件的模块:
UserComponent保存仅在用户登录时使用的类的实例。UserModule中提供的所有类。类在进一步的子组件(如活动和片段组件)中以“LocalSingleton”的形式提供
UserBindingModule定义属于UserComponent的活动子组件
DroperBinding模块定义哪些片段子组件属于DroperActivityComponent
UserManager处理用户登录/注销和所有进一步的活动注入
2。应用程序+活动+片段类