AliSoftware / Dip

Simple Swift Dependency container. Use protocols to resolve your dependencies and avoid singletons / sharedInstances!
MIT License
978 stars 75 forks source link

How to resolve UIViewController with runtime arguments? #192

Closed Narayane closed 6 years ago

Narayane commented 6 years ago

Hi,

I need to resolve a UIViewController with runtime arguments to do something like this following:

container.register(.unique) { (id: String, object: MyProtocol?) in try MyViewModel(repository: container.resolve(), id: id, object: object) as MyViewModelProtocol }

container.register(storyboardType: MyUIViewController.self, tag: "MyTag")
            .resolvingProperties { container, vc in
                vc.viewModel = try container.resolve(arguments: id, object) as MyViewModelProtocol
}

Is it possible?

Thanks.

ilyapuchka commented 6 years ago

This issue is not related to view controller registration but to any type that uses property injection instead of contractor injection. It's not possible to access runtime arguments in resolvingProperties closure. So you will need to register your view controller exactly the same way as any other component instead of using register(storyboardType:). You then can either just instantiate it from storyboard and inject your property before returning the value, or use constructor injection instead, the same way as in view model registration.

container.register(.unique) { (id: String, object: MyProtocol?) in try MyViewModel(repository: container.resolve(), id: id, object: object) as MyViewModelProtocol }

container.register(.unique, tag: "MyTag") { (id: String, object: MyProtocol?) in
    let storyboard = ...
    let vc = storyboard.instantiateViewController(...) as! MyUIViewController
    vc.viewModel = try container.resolve(arguments: id, object) as MyViewModelProtocol
    return vc
}

let vc = container.resolve(tag: "MyTag", arguments: id, object) as MyUIViewController
Narayane commented 6 years ago

Thanks for explanations. Great job with that lib :)