I'm trying to create a very simple app using the IoC framework for Fantom afIoc to become familiar with it. I tried this...
using afIoc
class Main {
Registry registry := IocService([AppModule#]).start.registry
@Inject
myPod::Version? version
Void main() {
echo("version is $version")
}
}
The Version class is
const class Version {
override Str toStr() {
"0.0.1"
}
}
The AppModule is
using afIoc
class AppModule {
static Void bind(ServiceBinder binder) {
binder.bind(myPod::Version#)
}
}
It compiles but prints version is null
. I fixed the problem by redefining my Main class:
using afIoc
class Main {
Registry registry := IocService([AppModule#]).start.registry
Void main() {
version := (myPod::Version) registry.serviceById("myPod::Version")
echo("version is $version")
}
}
But I'd like to understand the lifecycle of the afIoc Registry and why the Version service is not injected in my first version of the Main class. Can anyone explain, please?
I've seen people ask similar questions of other IoC frameworks... So lets look at what happens when you run the program:
Fantom instantiates the
Main
class.Fantom creates the
registry
field and assigns it to the result ofIocService([AppModule#]).start.registry
. This statement simply builds and returns the IoC registry.Fantom creates the
version
fields and defaults it tonull
.Fantom calls the
main()
method which prints out theversion
, which isnull
.Note that nowhere above have we asked IoC to meddle with our
Main
class. We just new'ed up the IoC Registry and set it to a field.If we want the IoC to inject values into a class we have to ask it to:
Or we could ask IoC to instantiate a new instance of
Main
for us:Note that many calls to
autobuild()
would create many instances ofMain
.For IoC to only create one instance of
Main
(a singleton), define it as a service inAppModule
and useregsitry.serviceById()
orregistry.dependencyByType()
- much as you discovered withVersion
.