Landon Patmore
10/24/2024, 7:40 PManvil, but I don't think that should matter here.
It looks like:
/** Wraps all dependency injection code. */
class DependencyInjectionConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
val extension = extensions.create<DependencyInjectionExtension>("di")
configurePlugins()
configureAnvil()
configureDependencies(extension)
}
}
private fun Project.configurePlugins() {
with(pluginManager) {
apply("com.squareup.anvil")
apply("com.google.devtools.ksp")
}
}
private fun Project.configureAnvil() {
configure<AnvilExtension> {
useKsp(contributesAndFactoryGeneration = true, componentMerging = true)
}
}
private fun Project.configureDependencies(extension: DependencyInjectionExtension) {
dependencies {
add("implementation", project(":common:di:public"))
if (extension.needsDaggerCompiler.getOrElse(false)) {
println("We are true")
add("ksp", libs.findLibrary("com-google-dagger-dagger-compiler"))
} else {
println("We are false")
}
}
}
}
abstract class DependencyInjectionExtension {
/** If your module contains any type of pure dagger modules, components, etc., set this to true. */
abstract val needsDaggerCompiler: Property<Boolean>
}
I've added it to my modules and set
di { needsDaggerCompiler = true }
On the modules that need it, but when I run the build, all modules no matter if they have been set to true are all false. I feel like I am missing something really obvious here, but no matter what I look up, it seems to show that what I wrote is correct, even though it is not, thanks!Landon Patmore
10/24/2024, 8:15 PMdependencies block within an afterEvaluate block for this to workPhilip W
10/24/2024, 9:18 PMVampire
10/24/2024, 11:34 PMafterEvaulate to "fix" something is like using Platform.runLater or SwingUtilities.runLater to "fix" a GUI problem.
You only do symptom treatment and move the problem to a later, harder to reproduce, harder to debug, harder to find, and harder to fix point in time instead of solving the actual problem.
The main earnings you get for using afterEvaluate is timing problems, ordering problems, and race conditions. You should avoid using it at almost any cost.
As you already recognized, your problem is that you read the property from the extension before the consumer had a chance to set it. By using afterEvaluate you gave it a chance to set it, but by now means you can be sure it will not change again after that.
Whenever you call get or similar on a Property at configuration time, you can be pretty sure you are doing something wrong, as you introduce ordering problems and race conditions doing so.
The sense of `Property`s is, that you do not evaluate them at configuration time, but only at execution time. At configuration time you only wire `Property`s and `Provider`s to other `Property`s or methods that know how to properly handle them like the addLater Philip mentioned.
In other situations where you definitely need the value at configuration time, my usual recommendation is to replace the property in the extension by a function in the extension and doing the logic that needs the value in the body of that function.Landon Patmore
10/28/2024, 5:15 PMdependencies.addLater function or parameterPhilip W
10/28/2024, 6:47 PMmyConfiguration.dependencies.addLater(provider{}) and DependencyHandler.add("myConfigName", provider {} )