Factory initialization with additonal property inj

2019-07-23 01:41发布

问题:

In my demo project I replaced the manual creation of a view controller with the factory-based creation within an assembly like so (as Jasper Blues demonstrated here: https://stackoverflow.com/a/24227246/397898)

// ApplicationAssembly

dynamic func mainStoryboard() -> AnyObject {
    return TyphoonDefinition.withClass(TyphoonStoryboard.self) {
        (definition) in

        definition.useInitializer("storyboardWithName:factory:bundle:") {
            (initializer) in

            initializer.injectParameterWith("Main")
            initializer.injectParameterWith(self)
            initializer.injectParameterWith(NSBundle.mainBundle())
        }

        definition.scope = TyphoonScope.Singleton
    }
}

// PersonListAssembly

dynamic func personListViewController() -> AnyObject {

        return TyphoonDefinition.withFactory(self.applicationAssembly.mainStoryboard(), selector: "instantiateViewControllerWithIdentifier:", parameters: {
            (factoryMethod) in

            factoryMethod.injectParameterWith("PersonListViewController")
        })
    }

But the view controller still needs some other dependencies. How can I inject the propery when doing this?

And actually I have two questions: All IBOutlets are nil, when I try to use the view controller like this. Am I missing something?

Correct answer based on Jasper's response

dynamic func personListViewController() -> AnyObject {

    return TyphoonDefinition.withClass(PersonListViewController.self) {
        (definition) in

        definition.factory = self.applicationAssembly.mainStoryboard()
        definition.useInitializer("instantiateViewControllerWithIdentifier:", parameters: { (factoryMethod) in

            factoryMethod.injectParameterWith("PersonListViewController")
        })

        definition.injectProperty("presenter", with: self.personListPresenter())
    }
}

回答1:

It seems the shortcut way of declaring a component that is emitted from another Typhoon component does not support this (yet). We'll open an issue. Meanwhile you can fall back to Typhoon 1.0 style API:

- (id)currentTheme
{
    return [TyphoonDefinition withClass:[PFTheme class] 
        configuration:^(TyphoonDefinition* definition)
    {
        definition.factory = [self themeFactory];
        [definition useInitializer:@selector(sequentialTheme)];
    }];
}

. . when you use this approach:

  • An initializer (with or without args) is actually an instance method on the object that will produce the component.
  • Additional properties, scope, etc can be set.

We created the short way as its a little confusing to refer to an 'initializer' that is in fact an instance method on the class creating the component. It looks like there was an oversight in adding a configuration block.



标签: swift typhoon