本文適合有必定的Dagger2使用基礎的同窗 android
下一篇:Dagger2多模塊項目Component組織方式選擇(二)git
Dagger2有兩種組織方式依賴(dependencies)和繼承(SubComponent).
對於單模塊簡單項目來講,兩種方式隨意,看我的喜歡,對於多模塊項目來講就要好好選擇了。 github
多模塊項目分兩種:segmentfault
這裏先給出結論:app
這篇文章咱們先來看第一種,這種方式其實就是Android官方上介紹的ide
假設項目模塊結構以下圖組件化
在普通多模塊項目中,app直接依賴news與user模塊,能夠直接引用其中的類this
app中放Appcomponent其它模塊用SubComponent繼承Appcomponentgoogle
base模塊spa
open class BaseApplication : Application() { override fun onCreate() { super.onCreate() instance = this } companion object { lateinit var instance: BaseApplication } }
app模塊
注意AppComponent不是放在base模塊
@Singleton @Component(modules = [AppModule::class]) interface AppComponent { @Component.Factory interface Factory { fun create(@BindsInstance context: Context): AppComponent } }
@Module class AppModule { @IntoSet @Provides fun provideString(): String { return "app" } }
class AppApplication : BaseApplication() { lateinit var appComponent: AppComponent override fun onCreate() { super.onCreate() appComponent = DaggerAppComponent.factory().create(this) } }
user模塊
@Module class UserModule { @IntoSet @Provides fun provideString(): String { return "user" } }
@UserScope @Subcomponent(modules = [UserModule::class]) interface UserComponent { @Subcomponent.Factory interface Factory { fun create(): UserComponent } }
news模塊
@Module class NewsModule { @IntoSet @Provides fun provideString(): String { return "news" } }
@Subcomponent(modules = [NewsModule::class]) interface NewsComponent { @Subcomponent.Factory interface Factory { fun create(): NewsComponent } }
根據SubComponent的原理NewsComponent和UserComponent必須在AppComponent註冊它們
@Module(subcomponents = [NewsComponent::class, UserComponent::class]) class AppModule { @IntoSet @Provides fun provideString(): String { return "app" } }
@Singleton @Component(modules = [AppModule::class]) interface AppComponent { @Component.Factory interface Factory { fun create(@BindsInstance context: Context): AppComponent } fun newsComponentFactory(): NewsComponent.Factory fun userComponentFactory(): UserComponent.Factory }
要生成NewsComponent和UserComponent必須先獲得AppComponent,經過如下方法來建立
val newsComponent = appComponent.newsComponentFactory().create() val userComponent = appComponent.userComponentFactory().create()
可是顯然,user,news模塊拿不到appComponent
這裏用兩個接口來得到
interface NewsComponentProvider { fun provideNewsComponent(): NewsComponent } interface UserComponentProvider { fun provideUserComponent(): UserComponent }
讓AppApplication實現這兩個接口
class AppApplication : BaseApplication(), NewsComponentProvider, UserComponentProvider { lateinit var appComponent: AppComponent override fun onCreate() { super.onCreate() appComponent = DaggerAppComponent.factory().create(this) } override fun provideNewsComponent(): NewsComponent { return appComponent.newsComponentFactory().create() } override fun provideUserComponent(): UserComponent { return appComponent.userComponentFactory().create() } }
而後user,news模塊中這樣獲取
val userComponent = (BaseApplication.instance as UserComponentProvider).provideUserComponent() val newsComponent = (BaseApplication.instance as NewsComponentProvider).provideNewsComponent()
一般UserComponent與NewsComponent只要一個實例,上面方法每次都他建一個新實例不合適,能夠把它們放到一個全局變量中去
object NewsComponentHolder { val newsComponent: NewsComponent by lazy { (BaseApplication.instance as NewsComponentProvider).provideNewsComponent() } } object UserComponentHolder { val userComponent: UserComponent by lazy { (BaseApplication.instance as UserComponentProvider).provideUserComponent() } }
最後在Activity中這樣用
class NewsActivity : AppCompatActivity() { @Inject lateinit var set: Set<String> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_news) NewsComponentHolder.newsComponent.inject(this) text.text = set.toString() } } class UserActivity : AppCompatActivity() { @Inject lateinit var set: Set<String> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_user) UserComponentHolder.userComponent.inject(this) text.text = set.toString() } }