当我的应用程序启动时,我会获取一个远程配置文件,其中包含配置其他依赖项所需的信息(URL等)。
我获取远程配置后,我有一个Config
对象,我需要提供给其他TyphoonDefinition
。
现在我也在使用plist storyboard集成。
我最初沿着将程序集注入加载Config对象的ViewController的路径,当我收到远程配置并创建Config对象时,我会以某种方式将其设置为程序集上的属性。我这样做希望我可以在定义中使用该属性,但这不起作用,我得到了:
2014-10-22 21:18:06.203 four[39840:516543] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'No component matching id 'setConfig:'.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010a3e63f5 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010a07fbb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010a3e632d +[NSException raise:format:] + 205
3 four 0x00000001070a011d -[TyphoonComponentFactory componentForKey:args:] + 148
4 CoreFoundation 0x000000010a2de22c __invoking___ + 140
5 CoreFoundation 0x000000010a2de082 -[NSInvocation invoke] + 290
6 CoreFoundation 0x000000010a36d456 -[NSInvocation invokeWithTarget:] + 54
7 four 0x000000010709d358 -[TyphoonBlockComponentFactory forwardInvocation:] + 276
我有什么方法可以在运行时将对象注入到程序集中吗?
有没有更清洁的方法来做我想做的事情?
我正在阅读运行时参数,这听起来像我需要的,但我真的不理解文档。
例如,我将此作为定义。我需要将运行时Config对象作为参数传递给构造函数。
- (id<ApiService>)apiService
{
return [TyphoonDefinition withClass:[ApiService class] configuration:^(TyphoonDefinition* definition) {}];
}
答案 0 :(得分:2)
使用运行时参数
例如,我将此作为定义。我需要传递运行时 将对象配置为构造函数的参数。
- (id<ApiService>)apiService { return [TyphoonDefinition withClass:[ApiService class] configuration:^(TyphoonDefinition* definition) {}]; }
尝试这样的事情:
- (id<ApiService>)apiServiceWithConfig:(Config *)config {
return [TyphoonDefinition withClass:[ApiService class] configuration:^(TyphoonDefinition* definition) {
// inject into property:
[definition injectProperty:@selector(config) with:config];
// inject into constructor:
[definition useInitializer:@selector(initWithConfig:) parameters:^(TyphoonMethod *initializer) {
[initializer injectParameterWith:config];
}];
}];
}
使用工厂定义
看看接下来的两个定义:
- (Config *)currentConfig {
return [TyphoonDefinition withFactory:[self configManager] selector:@selector(currentConfig)];
}
- (ConfigManager *)configManager {
return [TyphoonDefinition withClass:[ConfigManager class] configuration:^(TyphoonDefinition *definition){
definition.scope = TyphoonScopeSingleton;
}];
}
想象一下,你有一个下载远程配置的ConfigManager并将其存储为'currentConfig'属性,'configManager'定义描述了该对象。
然后检查'currentConfig'定义。该定义只返回在ConfigManager实例上调用'currentConfig'method的结果。
然后你可以将config注入:
- (id<ApiService>)apiService {
return [TyphoonDefinition withClass:[ApiService class] configuration:^(TyphoonDefinition* definition) {
[definition injectProperty:@selector(config) with:[self currentConfig]];
}];
}
但请确保在'apiService'创建期间加载currentConfig(而不是nil)。 (也许更好地注入ConfigManager - 然后如果currentConfig为nil,它将在稍后填充)
答案 1 :(得分:1)
几点:
- (void)registerDefinition:(TyphoonDefinition *)definition;
。 。你可能也不想在你的情况下这样做。
您 感兴趣的是:
TyphoonComponentFactoryPostProcessor和TyphoonComponentPostProcessor:
Typhoon有两种可以附加的接口,一种是TyphoonComponentFactoryPostProcessor,另一种是TyphoonComponentPostProcessor。它们在内部使用,但您也可以自己编写,并使用它们做各种很酷的事情。
TyphoonComponentFactoryPostProcessor:在构建组件之前修改组件的定义(配方)。
TyphoonComponentPostProcessor:构建后修改实例。
<强> TyphoonConfig:强>
现有的TyphoonComponentFactoryPostProcessor可用于您描述的任务。它被称为TyphoonConfigPostProcessor并且是described in the user guide here。
所有后处理器都可以在构建时(在程序集中)或在运行时附加,如下所示:
TyphoonConfigPostProcessor* configurer = [[TyphoonConfigPostProcessor alloc] init];
[configurer useResourceWithName:@"Configuration.plist"]];
[factory attachPostProcessor:configurer];
请注意,由于TyphoonComponentFactoryPostProcessor修改了 definitions ,如果您已经构建了具有单例范围的组件,则它们不会受到影响。您必须创建懒惰的单身人士,或致电[factory unload]
。
如何在启动后获得对TyphoonComponentFactory的引用?
您的应用中的任何内容都需要进行配置步骤&#39; Typhoon Aware&#39;。您可以使用以下方法执行此操作:
- (ConfigController *)configController
{
return [ConfigController withClass:[INFGiftDeliveryAddressController class]
configuration:^(TyphoonDefinition *definition)
{
[definition injectProperty:@selector(factory) with:self];
}];
。 。注入程序集时,您可以声明类型为TyphoonComponentFactory
的属性或任何程序集子类。它会以任何方式工作。此功能的文档is here。
在移动和桌面应用程序中,您的组件通常需要制作并且能够识别台风&#39;所以我们可以从一个对象图(例如视图控制器)继续到另一个(这是运行时参数功能可能有用的地方)。请注意,您正在编写自己的特定于域的程序集界面,因此Typhoon是非侵入性的#34;。在大多数情况下,您的应用不会直接引用任何Typhoon API。
我们在这里已经涵盖了很多,所以如果您有任何进一步的问题或需要澄清,请不要犹豫。