我在iOS上使用Typhoon进行依赖注入。
我已经注册了一个类ConfigProviderImpl
,这个类依赖于其他类。基本上,我想要一个方法loadConfig
在第一次被另一个对象请求ConfigProvderImpl
时调用。
我在其他语言中使用了依赖注入,这样的事情通常可以通过预先设置实例,调用方法,然后在容器中注册实例本身以使其处于正确的状态来解决。我目前正在使用Typhoon 1.6.9,它似乎没有能力注册实例。我也检查了wiki的2.0,但它仍然不允许这样做。
目前我正在使用:
[definition setBeforePropertyInjection:@selector(loadConfig)];
但这被称为每个时间请求该类。我意识到我可以使用一些dispatch_once
魔法,但我只是想知道是否有更清洁的方式?
答案 0 :(得分:2)
其他语言的依赖注入框架通常侧重于服务器端开发。因此,组件的默认范围是 singleton 。这是有道理的,因为服务器可能需要在给定时间为其任何一个服务执行用例。
然而,在桌面和移动开发中,我们通常一次只为 一个 用例提供服务。而且,特别是在移动设备上,我们有内存限制。因此,Typhoon默认引入了一个新的内存范围 - TyphoonScopeObjectGraph。使用此范围,组件解析期间的任何共享引用都将返回相同的实例。这意味着:
创建一个懒惰的单身人士:
当然,虽然这是默认设置,但不是 所有 组件都需要此行为。制作一个在第一次请求之前不会实例化的单例:
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:)
}
此功能的文档are here。