Почему afIoc не внедряет сервис в этом случае?
Я пытаюсь создать очень простое приложение, используя инфраструктуру IoC для Fantom afIoc, чтобы ознакомиться с ним. Я попробовал это...
using afIoc
class Main {
Registry registry := IocService([AppModule#]).start.registry
@Inject
myPod::Version? version
Void main() {
echo("version is $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
, Я исправил проблему, переопределив мой основной класс:
using afIoc
class Main {
Registry registry := IocService([AppModule#]).start.registry
Void main() {
version := (myPod::Version) registry.serviceById("myPod::Version")
echo("version is $version")
}
}
Но я хотел бы понять жизненный цикл реестра afIoc и почему сервис Version не внедряется в мою первую версию класса Main. Кто-нибудь может объяснить, пожалуйста?
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
}
}
Фантом создает
Main
учебный класс.Фантом создает
registry
поле и присваивает его результатIocService([AppModule#]).start.registry
, Этот оператор просто создает и возвращает реестр IoC.Фантом создает
version
поля и по умолчанию этоnull
,Фантом называет
main()
метод, который распечатываетversion
, которыйnull
,
Обратите внимание, что нигде выше мы не просили IoC вмешиваться с нашими Main
учебный класс. Мы только что создали реестр IoC и установили его в поле.
Если мы хотим, чтобы 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
,