1

我正在使用Typhoon进行 iOS 的依赖注入。

我已经注册了一个类,ConfigProviderImpl,它是由其他类所依赖的。基本上,我想要一个方法,在另一个对象请求loadConfig的第一次被调用。ConfigProvderImpl

我在其他语言中使用过依赖注入,类似的问题通常可以通过预先创建实例、调用方法、然后将实例本身注册到容器中来解决,这样它就已经处于正确的状态。我目前使用的是 Typhoon 1.6.9,它似乎没有注册实例的能力。我也检查了wiki的 2.0,但它仍然不允许这样做。

目前我正在使用:

[definition setBeforePropertyInjection:@selector(loadConfig)];

但是每次请求课程时都会调用它。我意识到我可以使用一些dispatch_once魔法,但我只是想知道是否有更清洁的方法?

4

1 回答 1

2

其他语言的依赖注入框架通常专注于服务器端开发。所以组件的默认范围是单例。这是有道理的,因为服务器可能需要在给定时间为其任何一项服务执行用例。

然而,在桌面和移动开发中,我们通常一次只为一个用例提供服务。而且,特别是在移动设备上,我们有内存限制。因此,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:)
}

此功能的文档在此处

于 2014-06-17T22:58:43.390 回答