Closed onlyamessenger closed 6 years ago
If you are creating controller in code you can pass all dependencies in init
and use auto-wiring (will work the same way even if there are not dependencies to pass in). If you still want to use init()
you'll have to make your properties for dependencies mutable to be able to inject them manually in resolvingProperties
, or use auto-injection.
The only thing that DipUI does is that it registers "dummy" factory which will never be called (unless controller is resolved manually and not created from storyboard) and calls resolve
as soon as controller is instantiated from storyboard. When you create controllers in code it's no different from resolving any other kind of types.
Sorry, I still don't understand how that would work, since ChatController
is not instantiated in the composition root. Could you perhaps provide a short example?
You don't have to instantiate view controllers in composition root. You can create a factory that will create this controller when you ask it. Container can play as such factory if you use it through some factory interface, not with resolve
:
protocol ChatViewControllerProvider {
func makeChatViewController() -> ChatViewController
}
extension Container: ChatViewControllerProvider {
func makeChatViewController() -> ChatViewController {
return try! resolve() as ChatViewController
}
}
// or
class ChatViewControllerFactory: ChatViewControllerProvider {
func makeChatViewController() -> ChatViewController {
return ChatViewController()
}
}
container.register { ChatViewControllerFactory() as ChatViewControllerProvider }
Okay, I think using what you described here would be best:
if you still want to use init() you'll have to make your properties mutable to be able to inject them manually in resolvingProperties
The only question I have then is how should ChatController be registered to enable resolvingProperties
to be called?
The same way as any other type.
container.register(ChatViewController.init).resolvingProperties { ... }
Thank you, I didn't see that registration use case in the docs. Are you accepting PR's for documentation? I think it would be useful to have some Clean Architecture use cases shown with DIP.
Getting the following compiler error:
Ambiguous reference to member 'init(nibName:bundle:)'
I think wiki contains excessive docs and enough examples, please check it. https://github.com/AliSoftware/Dip/wiki/Tips-&-Tricks#registering-using-initializersfactory-methods-v-50
Thanks, managed to convert ChatController so it's instantiated by StoryBoard. Couldn't get it to resolve properly otherwise.
When using StoryBoards to instantiate UIViewControllers, resolving dependencies is very straight forward. Currently, I do it as follows:
How would I accomplish this for a UIViewController that is created using init() and not instantiated by a StoryBoard? I really need this since some of the UIViewControllers in my project are created completely in code and have no StoryBoard files. I thought of getting a reference to container in the controller, but that would just be creating the ServiceLocator anti-pattern.
This is how these controllers are typically created in response to user actions: