uber/needle

How to inject dynamic dependency

chenjunpu opened this issue · 2 comments

In the Sample I saw the code is here, but I don't know how to call it ? and how to inject dynamic dependency gameComponent to loggedInViewController ?

class LoggedInComponent: PluginizedComponent<EmptyDependency>, LoggedInBuilder {

    var loggedInViewController: UIViewController {
        return shared {
            let viewController = LoggedInViewController(gameBuilder: gameComponent,
                                                        scoreStream: pluginExtension.mutableScoreStream,
                                                        scoreSheetBuilder: pluginExtension.scoreSheetBuilder)
            self.bind(to: viewController)
            return viewController
        }
    }

    var gameComponent: GameComponent {
        return GameComponent(parent: self)
    }

    // This demonstrates how to inject dynamic dependency into a child scope
    // as well as providing a unit test case for invoking the same child
    // scope constructor twice without generating duplicate code.
    func gameComponent(with dynamicDependency: String) -> GameComponent {
        return GameComponent(parent: self, dynamicDependency: dynamicDependency)
    }
}
class GameComponent: PluginizedComponent<GameDependency>, GameBuilder {

    let dynamicDependency: String

    override init(parent: Scope) {
        // Normally if we have a dynamic dependency, this constructor would not exist.
        // This fake value is just to get the code to compile for demonstration of
        // dynamic dependencies.
        self.dynamicDependency = ""
        super.init(parent: parent)
    }

    // Dynamic dependency constructor. Dynamic dependency provided by parent scope.
    init(parent: Scope, dynamicDependency: String) {
        self.dynamicDependency = dynamicDependency
        super.init(parent: parent)
    }
}

When you build the loggedInViewController (inside of RootViewController) you can pass additional data if you change the signature from a property to a function. After that, you can pass the data to the gameComponent.

You might want to checkout RIBs for more sophisticated examples. It does not use Needle, but the component interface is the same, so that you can use it in the same way.

@chenjunpu, I have just finished up an example project that shows the usage of both RIBs and Needle. Here I show an example of dynamic dependency. Although it seems like a cleaner solution may be static pass a stream of the given dependency, such as PlayerStream or 'X'Stream, etc.