Одной из особенностей библиотеки является возможность построения графа зависимостей после регистрации компонентов.
На основе этой возможности библиотека предлагает проверить этот граф, до начала использования. То есть регистрируем все зависимости, получаем граф, вызываем функцию проверки - а она проверяет, что все зарегистрировано верно.
Эта функция называется checkIsValid
и находится в созданном графе:
container.register(...)
container.register(...)
...
#if DEBUG
if !container.makeGraph().checkIsValid(checkGraphCycles: true) {
fatalError("invalid graph")
}
#endif
Подобная проверка не имеет смысла в релиз версии, так как граф зависимостей не меняется от запуска к запуску. Поэтому для экономии времени запуска советую функцию проверки заносить в predefine секцию.
Функция проверяет граф на: достижимость вершин, однозначность переходов, возможность создать объект. Булева переменная checkGraphCycles
позволяет отключить проверку циклов.
Все возникшие проблемы пишутся в лог, и если возникла критическая проблема, то функция проверки вернет false
. О том, что такое логирование можно почитать тут А ниже описаны все возможные ошибки, которые могут возникнуть во время проверки графа.
No initialization method for {Component}. And found reference on this component from {FromComponent}.
- подобная ошибка возникает в случае если нет метода инициализации у указанного компонента. Но при этом по графу зависимостей этот метод обязан быть, так как на объект есть переход, и он точно не может появиться из неоткуда. В случае если зависимость опциональная, то это будет не ошибкой, а предупреждением.No initialization method for {Component}. This component can be created using 'inject(into:...' or if created from storyboard. Otherwise it's incorrect. And found refrence on this component from {FromComponent}.
- предупреждение похоже на предыдущую ошибку, но в отличии от прошлой тут объект может быть создан, если это VC на storyboard или же вызывается функцияinject(into:
.No initialization method for {Component}. This component can be created using 'inject(into:...' or if created from storyboard. After first created component can be taken from cache. And found refrence on this component from {FromComponent}.
- инфо сообщение о том, что могут быть проблемы при создании компонента, но существует много случаев когда он создастся нормально, из-за того, что объект будет закэширован.No initialization method for {Component}. This component can be created using 'inject(into:...' or if created from storyboard. Otherwise it's incorrect.
- инфо сообщение о том что нет метода инициализации. Но при этом на этот компонент никто не ссылает. Такой компонент нельзя создавать функциейresolve
но он создастся в случае если это VC, или с помощью методаinject(into:
No initialization method for {Component}. This component can be created using 'inject(into:...' or if created from storyboard. After first created component can be taken from cache.
- инфо сообщение аналог предыдущему, но помимо этого после первого создания компонент будет закэширован. Его можно будет в дальнейшем получать обычным образом.
Ambiguity create object for type: {Type} into {Component}. Candidates: {Candidates}
- ошибка или предупреждение в зависимости от того является ли тип опционалом. Ошибка говорит о том, что в указанном компоненте есть зависимость, требующая указанного типа, но эту зависимость создать не удастся, так как есть несколько компонентов подходящих для внедрения. В случае подобной ошибки надо или убрать лишний компонент, или с помощью тэгов, имени, модульности добиться однозначности.
Invalid reference from {FromComponent} because not found component for type: {Type}
- Ошибка, если тип не опционал или не множественное внедрение, иначе предупреждение. Говорит о том, что из указанного компонент есть внедрение, которое не удастся внедрить, так как для него не зарегистрирован компонент. Чаще всего данная ошибка возникает из-за невнимательности, когда пишешь новый код - забываешь дописать регистрацию для чего либо.
Found unused component {Component}
- Ошибка возникает только если используютсяroot
компоненты. Оповещает о том, что некоторый компонент никогда не будет создан, если изначально могут создаваться только рутовые или single объекты. Подобная ошибка говорит или о устравшем и не нужном больше коде, или о том, что забыли внедрить данный компонент. Также возможной причиной может оказаться потерянный модификаторroot
у какого-то компонента.
-
Found a cycle used only init methods. Please tear cycle: {CycleDescription}
- ошибка. Указанный цикл состоит только из методов инициализации. Подобный цикл будет создаваться бесконечно. Для решения проблемы надо разорвать цикл хотя бы в одном месте - перенести внедрение из метода инициализации в свойства. -
Found a cycle without tears. Please tear cycle use '.injection(cycle: true...': {CycleDescription}
- ошибка. Указанный цикл не имеет указаний точек разрыва. Для устранению проблемы стоит исправить хотя бы одно внедрение, указавcycle: true
. Тем самым дав понять библиотеке, что вы согласны с этим циклом и контролируете ситуацию. -
Found a cycle where any components have lifetime 'prototype'. This cycle will be created indefinitely. Please change lifetime on 'objectGraph' or other. Cycle description: {CycleDescription}
- ошибка. Указанный цикл состоит только из компонентов с временем жизниprototype
. Обычно для всех объектов в цикле нужно использовать время жизниobjectGraph
или время жизни с кэшом, но обязательно хотя бы для одного. В случае же сprototype
объекты будут создаваться бесконечно. Для решения проблемы поменяйте время жизни хотя бы у одного компонента из цикла, а лучше у всех. -
Found a cycle where is first component have lifetime 'prototype'. This cycle maked incorrect. You can change lifetime on
objectGraphor other cached. Cycle description: {CycleDescription}
- ошибка. Может возникать только при использовании root компонент. Аналог предыдущей проблемы, но в данном случае объект с которого начинается цикл имеет время жизниprototype
, что однозначно приведет к двойному и более экземпляру этого объекта, и скорей всего к некорректному исполнению программы. Для решения проблемы, надо у первого (а возможно и у других) компонента из цикла заменить время жизни сprototype
наobjectGraph
или у другое время жизни отличное от prototype -
Found a cycle where is it components have lifetime 'prototype'. This cycle can maked incorrect, if call resolve from 'prototype' component. You can change lifetime on 'objectGraph' or ignore warning. Cycle description: {CycleDescription}
- предупреждение. Аналог предыдущей проблемы, но для ситуаций когда нельзя однозначно понять будет ли создан объект единожды или нет. Для того чтобы понять есть ли ошибка, нужно осознать с какого объекта начинается создание объектов - если сprototype
то это приведет к не желаемому результату. -
Found a cycle where is it components have different lifetimes. This cycle can make incorrect. If start resolve from 'prototype'/'objectGraph' you can reference from 'perContainer'/'perRun'/'single' on other object because there is an old resolve in cache. Cycle description: {CycleDescription}
- предупреждение. В указанном цикле используются разные время жизни, в том числе и кэширующие. Такой цикл может приводить к не желаемому поведению в случае если создание объекта начинается не с кэширующего времени жизни. Проблема в том, что после первого создания ссылки из закэшируемых объектов уже будут созданы и не обновятся, если вы повторно запросите объект не из кэша.