2017-06-18 38 views
3

我一直在使用Dagger 2一段時間,我仍然試圖弄清楚一些事情。有一件事我仍然不能很好地管理 正在爲不同的情況設置模塊和組件,就像一個有多個片段的活動。 我見過很多實現,大部分時間都有點不同。使用Dagger 2爲Android MVP設置模塊和組件 - 有多個片段的活動

因此,讓我公開我使用MVP的當前應用程序結構,如果我的實現沒有問題,我想要一些意見。

@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中,我通常只設置我的應用程序需要的單例。像SharedPreferences或與網絡請求相關的任何內容。 這個模塊和組件是不知何故的標準,我總是開始我的應用程序創建它們像這樣。

然後設置我爲活動模塊和部件,其將對ApplicationComponent

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

現在dependencie,MainActivity具有3個片段,我將創建片段3個模塊和1個組件

@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,首先在我的應用程序類中,然後在每個活動和片段中

applicationComponent = DaggerApplicationComponent.builder() 
      .applicationModule(new ApplicationModule(this)) 
      .build(); 

例如在WelcomeActivity,我實例這樣的:

DaggerActivityComponent.builder() 
      .activityModule(new ActivityModule(this)) 
      .applicationComponent(((MainApplication) 
getApplication()).getApplicationComponent()) 
      .build() 
      .inject(this); 

在MainActivity我做到這一點與上述相同,但我真的創建用於在其內部活動部件的吸氣劑。

然後在我的每一個片段,我實例是這樣的:

DaggerFragmentComponent.builder() 
      .homeFragmentModule(new HomeFragmentModule(this))    
    .activityComponent(((MainActivity)getActivity()).getActivityComponent()) 
      .build() 
      .inject(this); 

此時一切正常。我可以注入演示者和我想要的任何東西,但我不確定它是否是正確的方法。

您對我的實施有什麼看法?

此外,我還有一個Repository類,將用於每個演示者將Firebase中的信息顯示給UI。

你會爲此創建一個組件和模塊,然後讓所有的片段對它有依賴嗎?

希望我沒有問太多問題,但我真的很想清理我的想法。

謝謝

回答

2

您的設置非常好。絕對是我看到的最好的。

我想提出一些小的改動,讓你的生活更容易長遠。

子組件,而不是組件具有依賴性:

我還沒有看到一個用例,其中組件之間的依賴性指定比使用子更好。

子組件可以直接訪問父組件的整個對象圖。這有兩個好處:

  1. 可以很容易地利用該家長提供的對象的(零代碼)
  2. 可以很容易地改變對象的範圍(如移動某些物體的應用組件,以使它全球)

約定優於配置的一般原則在這種情況下適用於子組件。

無需活動和片段之間的區別:

我注意到了活動要求的對象圖通常非常相似,由碎片所需要的一個。

在我的MVC/MVP方法中,我將Activities和Fragments指定爲控制器,並使用一個ControllerComponent來將依賴注入到控制器中。但是,即使對MVC/MVP使用另一種方法(或者根本不使用),如果從概念上思考它們 - Activities和Fragments具有非常相似的功能。

因此,我建議有一個注入活動和片段的單一組件。

無需每次片段的模塊:

我已經回答了有關其每次活動/片段here一個組件/模塊的問題。請閱讀該答案 - 它還提供了與此相關的代碼示例以及所有上述建議。

恕我直言,模塊應按問題域分組依賴關係,而不是由將使用它們的組件。例如,一個電子商務應用程序可能有以下幾個模塊:NetworkingModuleCurrencyModuleCartModuleCheckoutModule等..

真正落實例子:

我已經開源了我自己的應用程序,前一段時間,並且,恕我直言,它具有相對較好的依賴注入結構。你可以查看這個結構here

我不滿意的這個DI結構的一個方面是,並不是所有的依賴都按域分佈在模塊中。你可以做得比這更好。

訂閱我的博客:

我覺得有點不舒服在這裏插上這一點,但我們現在正在錄製的匕首先進的視頻教程。我們在過去的一個月裏一直在研究這個教程,它應該在2-3周內做好準備。

本教程將詳細討論您要求的內容 - 如何構建Dagger代碼以實現可維護性。您可以訂閱我的博客www.techyourchance.com,以便在發佈時得到通知。

希望這有助於。

+0

谷歌Android架構藍圖Github回購MVP和Dagger2的例子,他們使用一個組件和模塊的每個活動與片段,一個主要組件和模塊的存儲和一個模塊的應用程序。你知道他們爲什麼這麼做嗎?一種解釋是防止某些類別的意外使用,但它值得嗎? – dragosiv

+0

@dragosiv我不知道他們爲什麼這樣做。您可以通過在github回購中提出問題來詢問他們。 – Vasiliy

+0

@dragosiv,如果這個答案對你有幫助 - 考慮接受它。 – Vasiliy

相關問題