Внедрение зависимостей в ViewControllers без раскадровки

Я тестировал Typhoon, используя раскадровки и интеграцию plist, определяя зависимости в своей сборке, и все работало, как и ожидалось. Зависимости от ViewControllerB вводятся должным образом, например, когда выполняется push-переход от ViewControllerA к ViewControllerB. Я видел, что instanceiateViewControllerWithIdentifier используется для внедрения свойств.

Однако у меня также есть устаревший код, который не использует раскадровку. Он использует XIB. Например, LegacyViewControllerA отправляет LegacyViewControllerB:

Это код в LegacyViewControllerA:

LegacyViewControllerB *legacyVCB = [[LegacyViewControllerB alloc] initWithNibName:@"LegacyViewControllerB" bundle:[NSBundle mainBundle]];
legacyVCB.paramOne = ...
legacyVCB.paramTwo = ...
[self.navigationController pushViewController:legacyVCB animated:YES];

Это сборка:

- (LegacyViewControllerB *)legacyVCB
{
    return [TyphoonDefinition withClass:[LegacyViewControllerB class]
                          configuration:^(TyphoonDefinition *definition) {
                              [definition injectProperty:@selector(apiClient)
                                                    with:[self myApiClient]];
    }];
}

При отладке viewDidLoad LegacyViewControllerB я ожидал, что зависимость apiClient уже внедрена, но это не так. Почему?

РЕДАКТИРОВАТЬ:

Я проверил пример приложения, и мне было интересно, есть ли способ не знать о сборке и/или импортировать Typhoon в ViewControllers. На самом деле мне очень понравилась интеграция с раскадровками, потому что я не упоминал Тайфун.

Итак, скажем, у меня нет раскадровки, тогда единственный способ внедрить мой ViewController — это сделать следующее?

MyApplicationAssembly *assembly = [[MyApplicationAssembly new] activate];
LegacyViewControllerB *legacyVCB = [assembly legacyVCB];
[self.navigationController pushViewController:legacyVCB animated:YES];

И пришлось изменить мою сборку на следующее:

- (LegacyViewControllerB *)legacyVCB
{
    return [TyphoonDefinition withClass:[LegacyViewControllerB class]
                          configuration:^(TyphoonDefinition *definition) {
                              [definition useInitializer:@selector(initWithNibName:bundle:)
                                              parameters:^(TyphoonMethod *initializer) {
                                                  [initializer injectParameterWith:@"LegacyViewControllerB"];
                                                  [initializer injectParameterWith:[NSBundle mainBundle]];
                                              }];
                              [definition injectProperty:@selector(apiClient)
                                                    with:[self myApiClient]];
    }];
}

Однако это тоже не работает для меня: [assembly legacyVCB] правильно возвращает экземпляр LegacyViewControllerB с введенным myApiClient, но при его нажатии ViewDidLoad LegacyViewControllerB не вводит его. Кажется, что нажатие на него создает новый LegacyViewControllerB, потому что адрес памяти отличается. Как вы думаете, почему это происходит?

Заранее спасибо.


person fernandospr    schedule 17.07.2015    source источник


Ответы (1)


Typhoon подключается к UIStoryboard, так что он работает так же, как обычная раскадровка с дополнительным преимуществом внедрения зависимостей, но поскольку Typhoon представляет собой контейнер для внедрения зависимостей, обычный способ получить внедренный экземпляр — запросить у Typhoon , через интерфейс сборки.

  • Вставьте сборку в контроллер представления раскадровки, который хочет представить контроллер без раскадровки.
  • Запросите сборку для встроенного экземпляра.

Пример:

UIViewController *controller = [assembly legacyVCB];
//Now push it into a container VC or subview

В примере приложения Typhoon показано множество подобных примеров.

person Jasper Blues    schedule 17.07.2015
comment
Да, это довольно просто. Я ответил на это как на отдельный вопрос для вас здесь: в зависимости от тайфуна/31487498#31487498" title="typhoon получить экземпляр класса, созданный тайфуном, независимо от тайфуна"> stackoverflow.com/questions/31487472/ - person Jasper Blues; 18.07.2015
comment
Спасибо, однако, если я отлаживаю viewDidLoad LegacyViewControllerB после [self.navigationController pushViewController:legacyVCB animated:YES];, я вижу, что он не имеет внедренной зависимости (apiClient). Кажется, что нажатие создает новый LegacyViewControllerB. Как вы думаете, почему это происходит? - person fernandospr; 18.07.2015
comment
Если это поможет понять мою проблему, я могу поделиться с вами примером проекта в Github с использованием раскадровки (работает, как ожидалось) и без раскадровки (которая не внедряется, как ожидалось). - person fernandospr; 18.07.2015
comment
Опубликовал проблему в новом вопросе: stackoverflow. ком/вопросы/31507439/ - person fernandospr; 20.07.2015