DenisBronx / FunctionalUseCases

23 stars 3 forks source link

Problem with DI #1

Open TurKurT656 opened 3 years ago

TurKurT656 commented 3 years ago

Hi I've tried this solution and I really enjoy using functional usecases. However there is a problem when it comes to DI injection frameworks. I'm using koin as DI framework and this is my problem: Injecting Functions without needing Qualifiers

DenisBronx commented 3 years ago

Hi!

I think you need to use named dependencies:

factory(named("GetVerificationCodeUseCase")) { get<AuthRepository>()::getVerificationCode }
factory(named("VerifyCodeUseCase")) { get<AuthRepository>()::verifyCode }

viewModel { LoginViewModel(get(named("GetVerificationCodeUseCase")), get(named("VerifyCodeUseCase"))) }

Ideally, you extract the names in constants so you don't have issues with the refactoring.

Also In your case, since the use cases are just the repository function you can do: viewModel { LoginViewModel(get<AuthRepository>()::getVerificationCode, get<AuthRepository>()::verifyCode) }

TurKurT656 commented 3 years ago

Thank you for the answer. But named dependency is the same as Qualifiers in Dagger. And I've mentioned that I don't want to handle this case without it. And IMHO the second solution doesn't look nice. Looks like there is no choice other than that using Qualifiers.

DenisBronx commented 3 years ago

oh sorry! I missed the qualifiers part, my bad.

I'm not that experienced with Koin but I think there is no other way, in Dagger works more or less the same. Yeah the second solution doesn't look nice, I agree but I just mentioned it as a quick workaround.

An alternative is using a simple manual factory instead of the Koin factory. Personally, I don't provide all the dependencies with the DI framework, I mix Dagger with manual DI (Dependency containers) that avoids issues when injecting functions, objects...

DenisBronx commented 3 years ago

@TurKurT656 I just had a look at koin and I found this way of providing use cases without using a qualifier

fun Scope.getGetVerificationCodeUseCase() = get<AuthRepository>()::getVerificationCode

fun Scope.getVerifyCodeUseCase() = get<AuthRepository>()::verifyCode

viewModel { 
    LoginViewModel(getGetVerificationCodeUseCase(), getVerifyCodeUseCase()) 
}

hope this will be of help, sorry for the late answer...