android-hilt
android-hilt copied to clipboard
hilt-processor-ksp error: "'public' function exposes its 'internal' parameter type" if implementation is internal
I have multi module project and inside module I have public interface
public interface UserRepository {
...
}
and internal implementation of this interface
@Bound
internal class UserRepositoryImpl @Inject constructor(): UserRepository {
...
}
With kapt processor It works fine because it's Java and it doesn't know about "internal" modifier:
@Module
@InstallIn(SingletonComponent.class)
public interface UserRepository_SingletonComponent_BindingsModule {
@Binds
@Singleton
@NonNull
UserRepository bindUserRepositoryImpl(@NonNull UserRepositoryImpl implementation);
}
But with ksp processor I'm receiving an error 'public' function exposes its 'internal' parameter type UserRepositoryImpl
:
@Module
@InstallIn(SingletonComponent::class)
public interface UserRepository_SingletonComponent_BindingsModule {
@Binds
public fun bindUserRepository(implementation: UserRepositoryImpl): UserRepository
}
Would be good if class that marked with annotation @Bound/@BoundTo has "internal" visibility modifier, than generated "*_BindingsModule" class would also have internal visibility modifier.
I'm concerned how Dagger and Hilt will handle internal module classes when they finally migrate to KSP.
Also, I'm a bit reluctant to implement an internal module in the first place. If the module is the single source of UserRepository
in the entire project (SingletonComponent
), then making it internal seems a bad smell to me.
Even if we agree that this change should be made, internal implementations should be separated from public implementations. Putting both in the same module could potentially break the latter. *_Internal
suffix is probably a good idea in this case.
I'll look into this, but in the meantime, here's a possible workaround (instead of @Bound
/@BoundTo
):
public interface UserRepository {
// ...
companion object {
@FactoryMethod
fun getInstance(): UserRepository = UserRepositoryImpl()
}
}
This way, internal implementation is not exposed by the public factory method, while the single source of UserRepository
is public.
EDIT: This will only work with KSP, as Kapt processor does NOT support factory methods in companion objects.