我正在尝试使用Fantom afIoc的IoC框架创建一个非常简单的应用程序来熟悉它。我试过这个......
using afIoc
class Main {
Registry registry := IocService([AppModule#]).start.registry
@Inject
myPod::Version? version
Void main() {
echo("version is $version")
}
}
Version类是
const class Version {
override Str toStr() {
"0.0.1"
}
}
AppModule是
using afIoc
class AppModule {
static Void bind(ServiceBinder binder) {
binder.bind(myPod::Version#)
}
}
它编译但打印version is null
。我通过重新定义我的Main类来解决问题:
using afIoc
class Main {
Registry registry := IocService([AppModule#]).start.registry
Void main() {
version := (myPod::Version) registry.serviceById("myPod::Version")
echo("version is $version")
}
}
但我想了解afIoc Registry的生命周期以及为什么Version服务没有在我的第一个Main类中注入。有人可以解释一下吗?
答案 0 :(得分:1)
我看到有人问过其他IoC框架的类似问题......那么让我们来看看运行该程序时会发生什么:
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实例化Main
类。
Fantom创建registry
字段并将其分配给IocService([AppModule#]).start.registry
的结果。该语句只是构建并返回IoC注册表。
Fantom会创建version
字段,并将其默认为null
。
Fantom调用main()
方法打印出version
,null
。
请注意,上面没有我们要求IoC使用我们的Main
类插入。我们刚刚新建了IoC Registry并将其设置为一个字段。
如果我们希望IoC将值注入类中,我们必须要求它:
Void main() {
registry.injectIntoFields(this)
echo("version is $version") // --> version is 0.0.1
}
或者我们可以要求IoC为我们实例化Main
的新实例:
registry.autobuild(Main#)
请注意,对autobuild()
的多次调用会创建许多Main
个实例。
要让IoC只创建一个Main
(单例)实例,请在AppModule
中将其定义为服务并使用regsitry.serviceById()
或registry.dependencyByType()
- 就像您发现的那样与Version
。