Вызов метода установки при первом запросе в Typhoon Framework

Я использую Typhoon для внедрения зависимостей с iOS.

Я зарегистрировал класс ConfigProviderImpl, от которого зависят другие классы. По сути, я хочу, чтобы метод loadConfig вызывался в первый раз, когда ConfigProvderImpl запрашивается другим объектом.

Я использовал внедрение зависимостей в других языках, и что-то подобное обычно можно было решить, создав экземпляр заранее, вызвав метод, а затем зарегистрировав сам экземпляр в контейнере, чтобы он уже был в правильном состоянии. В данный момент я использую Typhoon 1.6.9, и, похоже, у него нет возможности регистрировать экземпляры. Я также проверил вики для версии 2.0, и она по-прежнему не разрешает это.

На данный момент я использую:

[definition setBeforePropertyInjection:@selector(loadConfig)];

Но это вызывается каждый раз при запросе класса. Я понимаю, что мог бы использовать немного магии dispatch_once, но мне просто интересно, есть ли более чистый способ?


person Chris Shepherd    schedule 17.06.2014    source источник


Ответы (1)


Среды внедрения зависимостей для других языков часто ориентированы на разработку на стороне сервера. Таким образом, областью действия по умолчанию для компонентов является singleton. Это имеет смысл, учитывая, что серверу может потребоваться выполнить вариант использования для любой из своих служб в данный момент времени.

Однако при разработке для компьютеров и мобильных устройств мы обычно обслуживаем один вариант использования за раз. И, особенно на мобильных устройствах, у нас есть ограничения по памяти. Поэтому Typhoon вводит новую область памяти по умолчанию — TyphoonScopeObjectGraph. С этой областью действия любые общие ссылки во время разрешения компонента будут возвращать один и тот же экземпляр. Это значит, что:

  • Вы можете загрузить весь граф объектов, включая круговые зависимости (делегаты и т. д.). Для приложения iOS это обычно может быть контроллер представления.
  • После завершения варианта использования этот объектный граф может быть отброшен, а память восстановлена.

Чтобы создать ленивый синглтон:

Конечно, несмотря на то, что это значение по умолчанию, не для всех компонентов требуется такое поведение. Чтобы создать синглтон, который не создается до первого запроса на него:

definition.scope = TyphoonScopeSingleton; 
definition.lazy = YES;

После этого:

  • Ваш метод обратного вызова будет вызываться только один раз для синглтона.
  • Он не будет выполнен, пока компонент не будет использован.

Всего имеется четыре области видимости TyphoonScopeObjectGraph, TyphoonScopePrototype (всегда возвращает новый экземпляр), TyphoonScopesingleton и TyphoonScopeWeakSingleton. Дальнейшее объяснение каждого из них доступно в документации Typhoon.

Альтернативный подход:

Другой ваш подход заключался в регистрации экземпляра объекта в контейнере. В Typhoon нет простого способа зарегистрировать данный экземпляр для выполнения какой-либо роли. Однако вы можете внедрить любой объект и зарегистрировать компонент, который будет создавать другие компоненты в сборке. Поэтому мы можем сделать следующее:

- (id)configProvider
{
    return [TyphoonDefinition withClass:[ConfigProvider class] 
        configuration:^(TyphoonDefinition* definition){
            //Typhoon 1.x was more explicit (withDefintion, withBool, withInstance, etc)
            //in 2.0 you just use the word 'with'
            [definition injectProperty:@selector(config) with:someObject];
        }];
}

- (id)config
{
    return [TyphoonDefinition withFactory:[self configProvider] 
        selector:@selector(config)]; 
        //You can also have args here, eg @selector(configForEnv:)
}

Документация по этой функции здесь.

person Jasper Blues    schedule 17.06.2014
comment
Извините, я забыл упомянуть, что уже использовал прицел TyphoonScopeSingleton. Я не знал о ленивом варианте, хотя. Фабричный способ выглядит так, как будто он может делать то, что мне нужно. Спасибо! - person Chris Shepherd; 25.06.2014
comment
Также недавно добавлены некоторые новые функции конфигурации (документация ожидает рассмотрения): github.com/typhoon- фреймворк/Тайфун/issues/220 - person Jasper Blues; 25.06.2014