-
-
Save dmytroKarataiev/e92e96d29d7224fb38895a3cb7c255db to your computer and use it in GitHub Desktop.
Dagger Android 2.26 simple example with support for Singleton, PerActivity, PerFragment, and PerChildFragment scopes in Kotlin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is a super simplified example of how to use the dagger.android framework | |
// This example also shows how to scope subcomponents to higher level subcomponents: | |
// Activity -> Fragment -> Fragment | |
// It allows you to create a single instances of classes for an Activity and its Fragments. | |
// This example works with Dagger 2.26. | |
// App.kt | |
class App: Application(), HasAndroidInjector { | |
@Inject | |
lateinit var appDependency: AppDependency | |
@Inject | |
lateinit var androidInjector: DispatchingAndroidInjector<Any> | |
override fun onCreate() { | |
super.onCreate() | |
DaggerAppComponent.create().inject(this) | |
} | |
override fun androidInjector(): AndroidInjector<Any> { | |
return androidInjector; | |
} | |
} | |
// AppModule.kt | |
@Module(includes = [AndroidInjectionModule::class]) | |
abstract class AppModule { | |
@PerActivity | |
@ContributesAndroidInjector(modules = [MainActivityModule::class]) | |
abstract fun mainActivityInjector(): MainActivity | |
} | |
// AppComponent.jkt | |
@Singleton | |
@Component(modules = [AppModule::class]) | |
interface AppComponent { | |
fun inject(app: App) | |
} | |
// MainActivity.kt | |
// Could also extend DaggerActivity instead of implementing HasAndroidInjector | |
class MainActivity: Activity(), HasAndroidInjector { | |
@Inject | |
lateinit var appDependency: AppDependency // same object from App | |
@Inject | |
lateinit var activityDependency: ActivityDependency | |
@Inject | |
lateinit var fragmentInjector: DispatchingAndroidInjector<Any> | |
override fun onCreate(savedInstanceState: Bundle?) { | |
AndroidInjection.inject(this) | |
super.onCreate(savedInstanceState) | |
setContentView(R.layout.main_activity) | |
if (savedInstanceState == null) { | |
addFragment(R.id.fragment_container, MainFragment()) | |
} | |
} | |
override fun androidInjector(): AndroidInjector<Any> { | |
return fragmentInjector | |
} | |
private fun addFragment(@IdRes containerViewId: Int, fragment: Fragment) { | |
getFragmentManager.beginTransaction() | |
.add(containerViewId, fragment) | |
.commit() | |
} | |
} | |
// MainActivityModule.kt | |
@Module | |
abstract class MainActivityModule { | |
@PerFragment | |
@ContributesAndroidInjector(modules = [MainFragmentModule::class]) | |
abstract fun mainFragmentInjector(): MainFragment | |
} | |
// MainFragment.kt | |
class MainFragment : Fragment(), HasAndroidInjector { | |
@Inject | |
lateinit var appDependency: AppDependency // same object from App | |
@Inject | |
lateinit var activityDependency: ActivityDependency // same object from MainActivity | |
@Inject | |
lateinit var fragmentDependency: FragmentDependency | |
@Inject | |
lateinit var childFragmentInjector: DispatchingAndroidInjector<Any> | |
fun onAttach(context: Context?) { | |
AndroidInjection.inject(this) | |
super.onAttach(context) | |
} | |
fun onCreateView( | |
inflater: LayoutInflater, | |
container: ViewGroup?, | |
savedInstanceState: Bundle? | |
): View { | |
return inflater.inflate(R.layout.main_fragment, container, false) | |
} | |
fun onViewCreated(view: View?, savedInstanceState: Bundle?) { | |
super.onViewCreated(view, savedInstanceState) | |
if (savedInstanceState == null) { | |
addChildFragment(R.id.child_fragment_container, MainChildFragment()) | |
} | |
} | |
override fun androidInjector(): AndroidInjector<Any> { | |
return childFragmentInjector | |
} | |
private fun addChildFragment(@IdRes viewId: Int, fragment: Fragment) { | |
getChildFragmentManager() | |
.beginTransaction() | |
.add(viewId, fragment) | |
.commit() | |
} | |
} | |
// MainFragmentModule.kt | |
@Module | |
abstract class MainFragmentModule { | |
@PerChildFragment | |
@ContributesAndroidInjector(modules = [MainChildFragmentModule::class]) | |
abstract fun mainChildFragmentInjector(): MainChildFragment | |
} | |
// MainChildFragment.kt | |
class MainChildFragment : Fragment() { | |
@Inject | |
lateinit var appDependency: AppDependency // same object from App | |
@Inject | |
lateinit var activityDependency: ActivityDependency // same object from MainActivity | |
@Inject | |
lateinit var fragmentDependency: FragmentDependency // same object from MainFragment | |
@Inject | |
lateinit var childFragmentDependency: ChildFragmentDependency | |
fun onAttach(context: Context?) { | |
AndroidInjection.inject(this) | |
super.onAttach(context) | |
} | |
fun onCreateView( | |
inflater: LayoutInflater, @Nullable container: ViewGroup?, | |
savedInstanceState: Bundle? | |
): View { | |
return inflater.inflate(R.layout.main_child_fragment, container, false) | |
} | |
} | |
// MainChildFragmentModule.kt | |
@Module | |
abstract class MainChildFragmentModule { | |
} | |
// PerActivity.kt | |
@Scope | |
@Retention(RetentionPolicy.RUNTIME) | |
annotation class PerActivity | |
// PerFragment.kt | |
@Scope | |
@Retention(RetentionPolicy.RUNTIME) | |
annotation class PerFragment | |
// PerChildFragment.kt | |
@Scope | |
@Retention(RetentionPolicy.RUNTIME) | |
annotation class PerChildFragment | |
// AppDependency.kt | |
@Singleton | |
class AppDependency @Inject internal constructor() | |
// ActivityDependency.kt | |
@PerActivity | |
class ActivityDependency @Inject internal constructor() | |
// FragmentDependency.kt | |
@PerFragment | |
class FragmentDependency @Inject internal constructor() | |
// ChildFragmentDependency.kt | |
@PerChildFragment | |
class ChildFragmentDependency @Inject internal constructor() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment