square / anvil

A Kotlin compiler plugin to make dependency injection with Dagger 2 easier.
Apache License 2.0
1.31k stars 82 forks source link

Internal implementations for @ContributesBinding? #716

Closed ursusursus closed 1 year ago

ursusursus commented 1 year ago
interface IpAddressProvider {
    fun ipAddress(): String
}

@AppScope
@ContributesBinding(AppScope::class)
internal class IpAddressProviderImpl @Inject constructor(): IpAddressProvider {
    override fun ipAddress(): String {
        return "..."
    }
}
com.squareup.anvil.compiler.api.AnvilCompilationException: Back-end (JVM) Internal error: sk.o2.net.IpAddressProviderImpl is binding a type, but the class is not public. Only public types are supported.

Could this be supported?

I'm aware most don't care about this as they split their modules into api+impl and just leave the implementations public in the impl module. However, given the split is mostly a fix for compilation avoidance, which should get better in future, and at that point most could be collapsed to a single module with public interface and internal implementations

Thoughts? Feasible?

JoelWilcox commented 1 year ago

This isn't something we can support currently because the internal types end up getting exposed in the generated code. See #73 if you're interested in previous discussion around this. If you wanted to use the setup in the provided code snippet while keeping the Impl class internal, another option would be writing a provider method and creating the Impl in the method body so it's not exposed as part of the API.

ursusursus commented 1 year ago

by provider method do you mean @Provides in a @Module?

JoelWilcox commented 1 year ago

Yes that's correct; only work-around that came to mind for maintaining the internal visibility on your class impl.