简体   繁体   中英

Dagger singleton vs Kotlin object

To define a singleton, should I use Kotlin object declaration or to make an ordinary Kotlin class and inject it using dagger? In my opinion the first option is definitely easier but there may be a reason to use dagger in this situation that I'm not aware of.

Option 1 (notice object keyword):

object SomeUtil {
    // object state (properties)

    fun someFunction(number: Long) {
        // ...
    }
}

Option 2 (notice class keyword):

class SomeUtil {
    // object state (properties)

    fun someFunction(number: Long) {
        // ...
    }
}
@Module
class AppModule {

    @Provides
    @Singleton
    internal fun provideTheUtil() = SomeUtil()
}
class MainActivity : BaseActivity() {

    @Inject internal lateinit var util: SomeUtil
}

UPDATE 2019-07-03

@Blackbelt said in comments that we should prefer option 2 for testability. But libraries like MockK can mock object s too. So do you still think option 2 is the preferred one?

You might want to reconsider the need of NumberFormatUtil being a singleton. It might be cheaper if you use @Reusable with Dagger or even a factory without any scope directly.

If NumberFormatUtil is fairly simple and only provides a few utility methods, no state and no need for mocking in tests, you could use an object implementation, maybe using @JvmStatic for Java -inter-operability. But then you could go for global utility (extension) functions as well:

package xyz

fun formatNumber(number: Long) {
    // ...
}

fun Long.format() = formatNumber(this)

You should use option 2.

In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one "single" instance. This is useful when exactly one object is needed to coordinate actions across the system.

From: Singleton Pattern

So, a singleton is single instance in a scope. In case of Android, it is virtual machine instance running the app. In case you need custom scopes, you have to use option 2 only.

But, if you have only static methods inside the object you want to inject its better to keep them as global methods and even get rid of object . No need to inject anything. It is similar to a java class with only static methods (I mentioned this point as it is a usual way of creating Utility classes).

However, if the object also has some state. I would recommend going dagger way. The object way does not provide with dependency injection. It only creates a Singleton. Your purpose for using dagger is dependency injection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM