Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Peal committed May 22, 2022
1 parent edbbeca commit 77ac8c0
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import com.squareup.anvil.annotations.ContributesMultibinding
import dagger.multibindings.StringKey
import javax.inject.Inject

@ContributesMultibinding(WeatherScope::class)
@StringKey("WeatherChannel")
@ContributesMultibinding(WeatherScope::class)
class WeatherDataSources @Inject constructor() : WeatherDataSource {
override suspend fun getForecast(): List<Int> {
return listOf(72, 70, 75, 78, 74, 78, 79)
}
}

@ContributesMultibinding(WeatherScope::class)
@StringKey("WeatherUnderground")
@ContributesMultibinding(WeatherScope::class)
class WeatherUndergroundDataSource @Inject constructor(): WeatherDataSource {
override suspend fun getForecast(): List<Int> {
return listOf(73, 71, 76, 77, 75, 79, 89)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.gpeal.droidconanvilsample.feature.weatherdata

import com.gpeal.droidconanvilsample.lib.daggerscopes.utils.SingleIn
import com.gpeal.droidconanvilsample.lib.daggerscopes.WeatherScope
import com.gpeal.droidconanvilsample.lib.daggerscopes.utils.SingleIn
import com.gpeal.droidconanvilsample.lib.userprefs.UserPrefs
import com.gpeal.droidconanvilsample.lib.weatherdata.WeatherDataSource
import com.gpeal.droidconanvilsample.lib.weatherdata.WeatherRepository
import com.squareup.anvil.annotations.ContributesBinding
import javax.inject.Inject

@SingleIn(WeatherScope::class)
@ContributesBinding(WeatherScope::class, WeatherRepository::class)
@ContributesBinding(WeatherScope::class)
class WeatherRepositoryImpl @Inject constructor(
private val userPrefs: UserPrefs,
private val dataSources: Map<String, @JvmSuppressWildcards WeatherDataSource>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import com.gpeal.droidconanvilsample.lib.daggerscopes.WeatherScope
import com.gpeal.droidconanvilsample.lib.daggerscopes.utils.SingleIn
import com.squareup.anvil.annotations.ContributesSubcomponent
import com.squareup.anvil.annotations.ContributesTo
import com.squareup.anvil.annotations.MergeSubcomponent
import dagger.Subcomponent
import kotlinx.coroutines.CoroutineScope

@SingleIn(WeatherScope::class)
@ContributesSubcomponent(WeatherScope::class, AppScope::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ interface WeatherBindings {

class WeatherFragment : Fragment(R.layout.main_fragment), DaggerComponentOwner {
override val daggerComponent: WeatherComponent by fragmentComponent { _, app ->
// If you want a ViewModel scoped component, just instantiate this component inside of your ViewModel.
// You instantiate this component anywhere, really.
app.bindings<WeatherComponent.ParentBindings>().weatherComponentBuilder().create()
}

Expand Down
19 changes: 0 additions & 19 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,23 +1,4 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ import androidx.fragment.app.Fragment
* 2) Make sure your bindings interface is contributed to AppComponent, UserComponent, etc via `@ContributesTo(AppComponent::class)`.
* 3) Call context.bindings<YourModuleBindings>().inject(this) (Kotlin)
*/
inline fun <reified T : Any> Context.bindings() = bindings(T::class.java)
inline fun <reified T : Any> Context.bindings() = _bindings(T::class.java)

/**
* @see bindings
*/
inline fun <reified T : Any> Fragment.bindings() = bindings(T::class.java)
inline fun <reified T : Any> Fragment.bindings() = _bindings(T::class.java)

/** Use no-arg extension function instead: [Context.bindings] */
fun <T : Any> Context.bindings(klass: Class<T>): T {
/** Use no-arg extension function instead: [Context._bindings] */
@Suppress("FunctionName")
fun <T : Any> Context._bindings(klass: Class<T>): T {
// search dagger components in the context hierarchy
return generateSequence(this) { (it as? ContextWrapper)?.baseContext }
.plus(applicationContext)
Expand All @@ -37,14 +38,14 @@ fun <T : Any> Context.bindings(klass: Class<T>): T {
?: error("Unable to find bindings for ${klass.name}")
}

/** Use no-arg extension function instead: [Fragment.bindings] */
fun <T : Any> Fragment.bindings(klass: Class<T>): T {
// search dagger components in fragment hierarchy, then fallback to activity and application
/** Use no-arg extension function instead: [Fragment._bindings] */
fun <T : Any> Fragment._bindings(klass: Class<T>): T {
// Search dagger components in fragment hierarchy, then fallback to activity and application
return generateSequence(this, Fragment::getParentFragment)
.filterIsInstance<DaggerComponentOwner>()
.map { it.daggerComponent }
.flatMap { if (it is Collection<*>) it else listOf(it) }
.filterIsInstance(klass)
.firstOrNull()
?: requireActivity().bindings(klass)
?: requireActivity()._bindings(klass)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CoroutineScope
import java.util.concurrent.ConcurrentHashMap

/**
* Use this to create a dagger component scoped to the full lifecycle of a Fragment. Under the hood, this will be backed
* by a ViewModel and will have an equivalent lifecycle. That means that it will survive configuration changes.
*
* The factory will be given a a coroutine scope and the application object that can be used to bind instances to the
* component. The coroutine scope is the backing ViewModel's viewModelScope.
*/
inline fun <reified T : Any> Fragment.fragmentComponent(crossinline factory: (CoroutineScope, Application) -> T) = lazy {
ViewModelProvider(this)[DaggerComponentHolderViewModel::class.java].get(factory)
}
Expand Down

0 comments on commit 77ac8c0

Please sign in to comment.