首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Dagger 2为Android MVP设置模块和组件-具有多个片段的活动

用Dagger 2为Android MVP设置模块和组件-具有多个片段的活动
EN

Stack Overflow用户
提问于 2017-06-18 14:27:00
回答 1查看 1.1K关注 0票数 5

我已经和Dagger 2一起工作了一段时间了,我还在努力弄清楚一些事情。有一件事我还没有很好的管理,那就是为不同的情况设置模块和组件,比如一个有几个片段的活动。我已经看到了很多实现,而且大多数时候都有点不同。

所以,让我公开我目前的应用程序结构,使用MVP和我想要一些意见,如果我的实现是可以的或不。

代码语言:javascript
复制
@Module
public final class ApplicationModule {

private Context mContext;


public ApplicationModule(Context context){
    mContext = context;
}


public ApplicationModule(){
    mContext = null;
}

@Provides
Context provideContext(){
    return mContext;
}

@Singleton
@Provides
public SharedPreferences getAppPreferences(){
    return mContext.getSharedPreferences("CalorieApp",Context.MODE_PRIVATE);
 }
}

@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {

void inject(MainApplication mainApplication);

SharedPreferences sharedPreferences();

}

在这个AppModule中,我通常只设置我的应用程序所需要的Singleton。比如SharedPreferences或任何与网络请求相关的东西。这个模块和组件在某种程度上是标准的,我总是以这样的方式创建我的应用程序。

然后,我将模块和组件设置为活动,这将依赖于ApplicationComponent

代码语言:javascript
复制
@Module
public class ActivityModule {

private Activity activity;

public ActivityModule(Activity activity){
    this.activity = activity;
}

@Provides
Activity provideActivity(){
    return  activity;
 }
}

@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = 
  ActivityModule.class)
public interface ActivityComponent {

void inject(WelcomeActivity welcomeActivity);

void inject(MainActivity mainActivity);
}

现在,MainActivity有3个片段,我将为片段创建3个模块和一个组件

代码语言:javascript
复制
@Module
public class HomeFragmentModule {

private HomeFragmentContract.View mView;

public HomeFragmentModule(HomeFragmentContract.View view){
    mView = view;
}

@Provides
HomeFragmentContract.View provideHomeFragmentView(){
    return mView;
  }

}

@Module
public class ChartsFragmentModule {

private ChartsFragmentContract.View mView;

public ChartsFragmentModule(ChartsFragmentContract.View view){
    mView = view;
}

@Provides
ChartsFragmentContract.View provideChartsFragmentView(){
    return mView;
}
}

@Module
public class ProfileFragmentModule {

private ProfileFragmentContract.View mView;

public ProfileFragmentModule(ProfileFragmentContract.View view){
    mView = view;
}

@Provides
ProfileFragmentContract.View provideProfileFragmentContract(){
    return mView;
}

}

@PerFragment
@Component(dependencies = ActivityComponent.class ,
    modules = {ChartsFragmentModule.class, HomeFragmentModule.class, 
ProfileFragmentModule.class})
public interface FragmentComponent {

void inject(ChartsFragment chartsFragment);

void inject(HomeFragment homeFragment);

void inject(ProfileFragment profileFragment);
}

然后,我将不得不实例化Dagger,首先在我的应用程序类中,然后在每个活动和片段中。

代码语言:javascript
复制
applicationComponent = DaggerApplicationComponent.builder()
            .applicationModule(new ApplicationModule(this))
            .build();

例如,在WelcomeActivity中,我实例化它如下:

代码语言:javascript
复制
    DaggerActivityComponent.builder()
            .activityModule(new ActivityModule(this))
            .applicationComponent(((MainApplication) 
getApplication()).getApplicationComponent())
            .build()
            .inject(this);

在MainActivity中,我做的和上面一样,但是我正在为里面的活动组件创建一个getter。

然后,在我的每个片段中,我实例化如下:

代码语言:javascript
复制
    DaggerFragmentComponent.builder()
            .homeFragmentModule(new HomeFragmentModule(this))              
    .activityComponent(((MainActivity)getActivity()).getActivityComponent())
            .build()
            .inject(this);

在这一点上一切正常。我可以注射演讲者和任何我想要的东西,但我不确定这是否是正确的方法。

你觉得我的实现怎么样?

另外,我有一个存储库类,将在每个演示者中使用它来显示从Firebase到UI的信息。

您会为此创建一个组件和模块,然后使所有片段都依赖于它吗?

希望我没有问太多的问题,但我真的想清理我的想法。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-19 16:57:43

你的设置很好。绝对是我见过的最好的。

我想建议几个小的改变,使你的生活更容易从长远来看。

子组件而不是组件依赖关系:

我还没有看到指定组件之间的依赖比使用子组件更好的用例。

子组件可以直接访问父组件的整个对象图。这有两个优点:

  1. 使使用父对象提供的对象变得容易(零代码)
  2. 可以方便地更改对象的作用域(例如,将一些对象移动到应用程序组件以使其具有全局性)

在这种情况下,约定优于配置的一般原则适用于子组件。

不需要区分活动和片段:

我注意到活动所需的对象图通常非常类似于片段所需的对象图。

在MVC/MVP方法中,我将活动和片段指定为控制器,并使用单个ControllerComponent将依赖项注入控制器。

然而,即使使用MVC/MVP的另一种方法(或者根本不使用),如果从概念上考虑它们--活动和片段具有非常相似的功能。

因此,我建议有一个注入活动和碎片的单一组件。

每个片段不需要一个模块:

我已经回答了一个关于每个活动/片段这里都有一个组件/模块的问题。请阅读这个答案--它还提供了与此相关的代码示例,以及所有上述建议。

IMHO,模块应该按问题域而不是将使用它们的组件分组依赖关系。例如,电子商务应用程序可以有以下模块:NetworkingModuleCurrencyModuleCartModuleCheckoutModule等.

实实现示例:

不久前,我已经开放了我自己的应用程序,而且,IMHO,它有相对良好的依赖注入结构。您可以查看此结构这里

我还不满意这个DI结构的一个方面,即并非所有依赖项都是按域在模块中分布的。你可以做得更好。

订阅我的博客:

我觉得有点不舒服,在这里插入,但我们正在录制一个先进的视频教程上的匕首现在。在过去的一个月里,我们一直在编写本教程,它应该会在2-3周内完成。

本教程将讨论您所要求的内容--如何构造用于可维护性的Dagger代码。您可以在www.techyourchance.com订阅我的博客,以便在发布时得到通知。

希望这能帮上忙。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44615986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档