I regularly need to wire cycles, and this is no problem using the DI container I wrote. Unfortunately the wiring is part of the property declaration, and this results in a recursive problem during type checking. Adding an explicit type will solve this:
class CyclesSgd(provided: Provided) : SubGraphDefinition(provided) {
interface Provided : ProvidedBase
// Explicit property type added here to prevent recursive problem
val mainMenu: Definition<MainMenu> by Singleton { MainMenu() }
.wire {
it.eatStep = req(eatMenu)
it.drinkStep = req(drinkMenu)
}
val eatMenu by Singleton { EatMenu() }
.wire { it.quitStep = req(mainMenu) }
val drinkMenu by Singleton { DrinkMenu() }
.wire { it.quitStep = req(mainMenu) }
}
In this case the extra type declaration (Definition<MainMenu>
) is relatively short, so it does not pollute the code too much. But in actual programs some type declarations are quite verbose, making the object definitions harder to read.
If I change the class to this, the extra type declaration is not needed. But now the object declaration has to be split in 2 properties: 1 for the delegate and 1 for the property itself. And the wiring (and other object life cycle functions) are separated from the object creation (because you cannot have multiple init
blocks):
class CyclesSgd(provided: Provided) : SubGraphDefinition(provided) {
interface Provided : ProvidedBase
// 2 properties instead of 1, and the life cycle functions are down below
val mainMenuDelegate = Singleton { MainMenu() }
val mainMenu by mainMenuDelegate
val eatMenuDelegate = Singleton { EatMenu() }
val eatMenu by eatMenuDelegate
val drinkMenuDelegate = Singleton { DrinkMenu() }
val drinkMenu by drinkMenuDelegate
init {
mainMenuDelegate.wire {
it.eatStep = req(eatMenu)
it.drinkStep = req(drinkMenu)
}
eatMenuDelegate.wire { it.quitStep = req(mainMenu) }
drinkMenuDelegate.wire { it.quitStep = req(mainMenu) }
}
}
So I want the semantics of the second code snippet, but with a shorter syntax, and with all the behavior for an object definition close together. Is this possible?