1

假设我有两个班级FooBar. Bar我可以独立于构建 a Foo,但Foo需要 a Bar。在 Typhoon 中,我定义了这两个组件并在我的应用程序中使用它们,但是在运行时构建我传入的 a 似乎作为 a而不是我传入的Foo那个传递给另一个组件。barIdBar<TyphoonInjectionByRuntimeArgument: 0x15ea4670, type=Undifined>NSString

我可能做错了。

我应该怎么做?

@implementation Assembly

-(Foo *)fooWithFooId:(NSString *)fooId andBarId:(NSString *)barId {
  return [TyphoonDefinition withClass:[Foo class] configuration:^(TyphoonDefinition* definition) {
    [definition useInitializer:@selector(initWithFooId:andBar:) parameters:^(TyphoonMethod *initializer) {
        [initializer injectParameterWith:fooId];
        [initializer injectParameterWith:[self barWithId:barId]];
    }];
  }];
}

-(Bar *)barWithBarId:(NSString *)barId {
  return [TyphoonDefinition withClass:[Bar class] configuration:^(TyphoonDefinition* definition) {
    [definition useInitializer:@selector(initWithBarId:) parameters:^(TyphoonMethod *initializer) {
      [initializer injectParameterWith:barId];
    }];
  }];
}

@end

////////

@implementation Foo

-(instancetype) initWithFooId:(NSString *)fooId andBar:(Bar *)bar
{
  self = [super init];
  self.fooId = fooId;
  self.bar = bar;
  return self;
}

@end

@implementation Bar

-(instancetype) initWithBarId:(NSString *)barId
{
  self = [super init];
  self.barId = barId;
  return self;
}

@end

更新:

进一步审查后,该问题似乎是由在定义中使用运行时参数为另一个定义构建另一个参数引起的。看下面的用法NSString

@implementation Assembly

-(Foo *)fooWithFooId:(NSString *)fooId andBazId:(NSString *)bazId {
  return [TyphoonDefinition withClass:[Foo class] configuration:^(TyphoonDefinition* definition) {
    [definition useInitializer:@selector(initWithFooId:andBaz:) parameters:^(TyphoonMethod *initializer) {
        [initializer injectParameterWith:fooId];
        [initializer injectParameterWith:[self bazWithPathToBaz:[NSString stringWithFormat:@"/some/path/to/baz/%@", bazId]]];
    }];
  }];
}

-(Baz *)bazWithPathToBaz:(NSString *)bazPath {
  return [TyphoonDefinition withClass:[Baz class] configuration:^(TyphoonDefinition* definition) {
    [definition useInitializer:@selector(initWithBazPath:) parameters:^(TyphoonMethod *initializer) {
      [initializer injectParameterWith:bazPath];
    }];
  }];
}

@end

当被调用时,传入初始化器的路径将是"/some/path/to/baz/<TyphoonInjectionByRuntimeArgument: 0x15ea4670, type=Undifined>"

4

1 回答 1

0

你是如何获得你的构建实例的Foo?上面的汇编代码看起来不错,但请记住以下几点:

  • 构建时:程序集返回TyphoonDefinition. Typhoon 检测此程序集以收集它在运行时返回已构建实例所需的信息。这包括使用代理(的实例)注入运行时参数TyphoonInjectionByRuntimeArgument
  • 运行时:程序集现在根据定义中定义的规则返回构建的组件。(它实际上是一个指向 a 的代理TyphoonComponentFactory)。

创建一个或多个程序集后,要使程序集返回构建的组件,需要执行以下操作:

- (void)testFoobar
{
    //Pass in a not-built assembly to TyphoonComponentFactory
    TyphoonComponentFactory *factory =
        [TyphoonBlockComponentFactory factoryWithAssemblies:@[[Assembly assembly]]]; 

    //Now we have a built assembly
    Assembly *builtAssembly = (Assembly*) factory;

    Foo *builtFoo = [builtAssembly fooWithFooId:@"1234" andBarId:@"5678"];
    NSLog(@"%@", builtFoo);
}

结果: <Foo: self.fooId=1234, self.bar=<Bar: self.barId=5678>>

(或者在应用程序的情况下,您可以使用 plist-integration 引导 Typhoon 并注入应用程序委托。请注意,您可以将程序集本身注入到任何组件中,无论是作为TyphoonComponentFactory或冒充您的程序集接口之一。这很有用从一个对象图(例如视图控制器)转换到另一个。)


编辑:

尽管这不是最初的意图,但在大多数情况下,您还可以在程序集中使用运行时参数,我们现在在自己的应用程序中执行此操作。例如:

- (OfferManager *)offerManager
{
    return [TyphoonDefinition withClass:[OfferManager class] 
        configuration:^(TyphoonDefinition *definition) {
        [definition useInitializer:@selector(initWithEngine:) 
            parameters:^(TyphoonMethod *initializer) {

            [initializer injectParameterWith:
                [self engineWithPollingInterval:@120 cacheExpire:@3600]];
        }];
    }];
}

. . 但目前不可能创建一个顶级定义,它是另一个带有运行时参数的定义的结果。例子:

- (Engine*) preConfiguredEngine {
    return [self engineWithPollingInterval:@120 cacheExpire:@3600];
} 

. . 原因很简单,如果你需要这个我们可以看看。

于 2014-12-09T23:54:43.457 回答