简体   繁体   中英

Typhoon Storyboard: Inject an IBOutlet View to a Controller dependency

I have a storyboard that has a view in it connected to his controller using an outlet. In the same controller I want to inject an object that needs access to that view. Instead of passing that view manually to the object I would like to inject it automatically but I don't know how and If I can achieve that with the current code structure.

class LoadingViewController: UIViewController {
    @IBOutlet weak var loadingView: UIActivityIndicatorView!
    private(set) var loadingViewModel: LoadingViewModel! // Dependency Injection
}

// Assembly

dynamic func loadingViewController() -> AnyObject {
    return TyphoonDefinition.withClass(LoadingViewController.self) {
        (definition) in
        definition.injectProperty("loadingViewModel", with:self.loadingViewModel())
    }
}

dynamic func loadingViewModel() -> AnyObject {
    return TyphoonDefinition.withClass(LoadingViewModel.self) {
        (definition) in
        definition.injectProperty("loadingView", with:???) // I want loadingViewController.loadingView 
    }
}

I think it has something to do with run-time arguments and circular dependency

That's a good one. We have to consider the life-cycle between the Storyboard created objects and Typhoon.

Have you tried something like:

//The view controller 
dynamic func loadingViewController() -> AnyObject {
    return TyphoonDefinition.withClass(LoadingViewController.self) {
        (definition) in
        definition.injectProperty("loadingViewModel",     
            with:self.loadingViewModel())
        definition.performAfterInjections("setLoadingViewModel", arguments: ) {
            (TyphoonMethod) in 
            method.injectParameterWith(self.loadingViewModel())
        }
    }
}

dynamic func view() -> AnyObject {
    return TyphoonDefinition.withFactory(self.loadingViewController(), 
        selector:"view")
}

dynamic func loadingViewModel() -> {
    return TyphoonDefinition.withClass(SomeClass.class) {
        (definition) in
        definition.injectProperty("view", with:self.view())
    }
}
  • Creates a definition for the view, instructing Typhoon that it will be emitted from the loadingViewController
  • Creates a definition for the loadingViewModel that has view injected.
  • After the loadingViewController , and therefore view has been created, inject the loadingViewModel as the last step.

I don't recall if the scope pool is cleared before calling performAfterInjections . If is is you might need to set the scope of loadingViewController to TyphoonScopeWeakSingleton instead of the default TyphoonScopeObjectGraph .

Because of the interplay between Typhoon and Storyboards it might be just simpler to manually provide the instance in eg viewDidLoad . But can you give the above a try and get back to me?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM