为什么afIoc在这种情况下不会注入服务?

时间:2014-08-09 01:38:50

标签: fantom

我正在尝试使用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类中注入。有人可以解释一下吗?

1 个答案:

答案 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
  }    
}
  1. Fantom实例化Main类。

  2. Fantom创建registry字段并将其分配给IocService([AppModule#]).start.registry的结果。该语句只是构建并返回IoC注册表。

  3. Fantom会创建version字段,并将其默认为null

  4. Fantom调用main()方法打印出versionnull

  5. 请注意,上面没有我们要求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