Reputation: 1254
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?
Upvotes: 1
Views: 32
Reputation: 5139
I've seen people ask similar questions of other IoC frameworks... So lets look at what happens when you run the program:
using afIoc
class Main { //................................................... 1
Registry registry := IocService([AppModule#]).start.registry //.. 2
@Inject
myPod::Version? version //....................................... 3
Void main() {
echo("version is $version") //................................. 4
}
}
Fantom instantiates the Main
class.
Fantom creates the registry
field and assigns it to the result of IocService([AppModule#]).start.registry
. This statement simply builds and returns the IoC registry.
Fantom creates the version
fields and defaults it to null
.
Fantom calls the main()
method which prints out the version
, which is null
.
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:
Void main() {
registry.injectIntoFields(this)
echo("version is $version") // --> version is 0.0.1
}
Or we could ask IoC to instantiate a new instance of Main
for us:
registry.autobuild(Main#)
Note that many calls to autobuild()
would create many instances of Main
.
For IoC to only create one instance of Main
(a singleton), define it as a service in AppModule
and use regsitry.serviceById()
or registry.dependencyByType()
- much as you discovered with Version
.
Upvotes: 1