Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Koin No definition found for class, but already declared

Im trying to implement a Permission Injection using Koin as my D.I however when i execute my ViewModel that requires the PermissionRepository i keep receiving the error.

No definition found for class:'ni.com.repository.PermissionRepositoryImplement'. Check your definitions!

the current structure of the project is this.

BaseApplication

class BaseApplication : Application() {
    companion object{
        lateinit var context: BaseApplication
        val allAppModules = listOf(coilModule, permissionsModule, blurModule, remoteDataSourceModule, preferencesModule, databaseModule, viewModelModule)
    }

    override fun onCreate() {
        super.onCreate()
        context = this
        startKoin {
            androidLogger()
            androidContext(this@BaseApplication)
            modules(allAppModules)
        }
        if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
    }
}

PermissionModule however i need an Activity to display the request for permissions. And following the Jetpack Navigation, i use my MainActivity as Base and injected in the Repository

val permissionsModule = module {
    scope<MainActivity> {
        scoped {
            PermissionRepositoryImplement(get<MainActivity>())
        }
    }
}

ViewModel Module

val viewModelModule = module {
    viewModel { PermissionViewModel(get()) }
}

then comes the PermissionRepositoryImplement

class PermissionRepositoryImplement(private val activity: Activity){
    companion object{
        private val map = Permission.values().associateBy(Permission::permissionValue)
        operator fun get(value: String) = (map[value] ?: error("NOT FOUND"))
    }

    enum class Key {
        granted, denied, forbidden
    }

    enum class Permission(val permissionValue: String) {
        WRITE_EXTERNAL_STORAGE(Manifest.permission.WRITE_EXTERNAL_STORAGE), READ_EXTERNAL_STORAGE(Manifest.permission.READ_EXTERNAL_STORAGE), CAMERA(Manifest.permission.CAMERA), INTERNET(Manifest.permission.INTERNET), INTERNET_STATE(Manifest.permission.ACCESS_WIFI_STATE), NETWORK_STATE(Manifest.permission.ACCESS_NETWORK_STATE),
    }

    private var result = HashMap<String, String>()

    fun requestPermission(permissionName: String): HashMap<String, String> {
        activity.let {
            it.askPermissions(get(permissionName).permissionValue) {
                onGranted {
                    result[permissionName] = Key.granted.name
                }
                onDenied {
                    result[permissionName] = Key.denied.name
                }
                onShowRationale { request ->
                    Snackbar.make(it.findViewById(R.id.container), String.format(it.getString(R.string.permissionRequested), Permission.values().filter { p -> p.permissionValue == permissionName }[0]), Snackbar.LENGTH_INDEFINITE)
                        .setAction("Retry") { request.retry() }
                        .show()
                }
                onNeverAskAgain {
                    result[permissionName] = Key.forbidden.name
                }
            }
        }
        return result
    }
}

and finally the PermissionViewModel

class PermissionViewModel (private val permissionImplement: PermissionRepositoryImplement): ViewModel() {

    private val _uiState = MutableLiveData<CredentialsDataState>()
    val uiState: LiveData<CredentialsDataState> get() = _uiState

    fun requestPermission(){
        viewModelScope.launch {
            runCatching {
                emitUiState(showProgress = true)
                permissionImplement.requestPermission(PermissionRepositoryImplement.Permission.CAMERA.permissionValue)
            }.onSuccess {
                emitUiState(result = Event(it))
            }.onFailure {
                emitUiState(error = Event(R.string.error))
            }
        }
    }

    private fun emitUiState(showProgress: Boolean = false, result: Event<HashMap<String, String>>? = null, error: Event<Int>? = null){
        val dataState = CredentialsDataState(showProgress, result, error)
        _uiState.value = dataState
    }

    data class CredentialsDataState(val showProgress: Boolean, val result: Event<HashMap<String, String>>?, val error: Event<Int>?)
}

until this section everything should work as koin need it. But im always receiving the error that my PermissionRepositoryImplement isn't defined...

like image 269
Luis Cardoza Bird Avatar asked Nov 06 '22 08:11

Luis Cardoza Bird


1 Answers

val permissionsModule = module {
    scope<MainActivity> {
        scoped {
            PermissionRepositoryImplement(get<MainActivity>())
        }
    }
}

You have not provided the MainActivity instance to koin. That's why you are getting error.

As per my understanding we should not try to create android component{activity, broadcast receiver, service, content provider} I will suggest extend PermissionRepositoryImplement with fragment.

like image 145
Rahul Singhal Avatar answered Nov 14 '22 22:11

Rahul Singhal