Hello guys,
I investigated a possibility to pass arguments if I had circular dependencies. For example I have 3 objects which links each other:
protocol LoginViewInput {}
protocol LoginViewOutput {
func didTriggerViewDidLoad()
}
protocol LoginInteractorInput {
func executeRequest()
}
class LoginViewController: UIViewController, LoginViewInput {
var output: LoginViewOutput?
var key: String?
override func viewDidLoad() {
super.viewDidLoad()
print("inject view key: \(key)")
self.output?.didTriggerViewDidLoad()
}
}
class LoginPresenter: LoginViewOutput {
var view: LoginViewInput?
var interactor: LoginInteractorInput?
var key: String?
func didTriggerViewDidLoad() {
print("inject presenter key: \(key)")
self.interactor?.executeRequest()
}
}
class LoginInteractor: LoginInteractorInput {
var output: LoginViewOutput?
var view: LoginViewInput?
var key: String?
func executeRequest() {
print("inject interactor key: \(key)")
}
}
So in my business code I'd like to inject some object when resolving dependencies.
let view = self.mainAssembler?.resolver.resolve(LoginViewInput.self, argument: "awesome version parameter")
I wrote the following Assembly.
class LoginAssembly: Assembly {
func assemble(container: Container) {
container.register(LoginViewInput.self) { (r, version: String) in
let controller = LoginViewController(nibName: "LoginViewController", bundle: nil)
controller.key = version
return controller
}.initCompleted { r, i in
let controller = i as! LoginViewController
controller.output = r.resolve(LoginViewOutput.self)
// possible I need to write here something like this
// controller.output = r.resolve(LoginViewOutput.self, argument: version)
}
container.register(LoginViewOutput.self) { (_, version: String) in
let presenter = LoginPresenter()
presenter.key = version
return presenter
}.initCompleted { r, i in
let presenter = i as! LoginPresenter
presenter.view = r.resolve(LoginViewInput.self)
presenter.interactor = r.resolve(LoginInteractorInput.self)
// possible I need to write here something like this
// presenter.interactor = r.resolve(LoginInteractorInput.self, argument: version)
// presenter.view = r.resolve(LoginViewInput.self, argument: version)
}
container.register(LoginInteractorInput.self) { (_, version: String) in
let interactor = LoginInteractor()
interactor.key = version
return interactor
}.initCompleted { r, i in
let interactor = i as! LoginInteractor
interactor.output = r.resolve(LoginViewOutput.self)
interactor.view = r.resolve(LoginViewInput.self)
// possible I need to write here something like this
// interactor.output = r.resolve(LoginViewOutput.self, argument: version)
// interactor.view = r.resolve(LoginViewInput.self, argument: version)
}
}
}
But I don't know how to pass version parameter in initCompleted block to resolve dependencies. Does anybody know how to resolve it? Thank you in advance!
Hi @igorkotkovets! Let me take time to read your code. Thanks!
@yoichitgy Great! I'm waiting for your feedback!
@yoichitgy be free to ask me if you need more details.
What if Resolver object will grab runtime arguments somehow explicitly and they will be accessible in initComplented block?
Plz look on dummy code below. I don't know how Resolver will store runtime argument, just my thoughts
container.register(LoginViewOutput.self) { (resolver: Resolver, version: String) in
let presenter = LoginPresenter()
presenter.key = version
resolver.save(version) // save runtime argument
return presenter
}.initCompleted { (resolver, presenter) in
let presenter = presenter as? LoginPresenter
let version = resolver.get() // get runtime argument
presenter?.interactor = r.resolve(LoginInteractorInput.self, argument: version)
presenter?.view = r.resolve(LoginViewInput.self, argument: version)
presenter?.key = version
}
Thanks @igorkotkovets. I already have a lot of question issues in this project, so I will come back here after answering the questions.
@igorkotkovets
try create new variable after:
func assemble(container: Container)
like:
func assemble(container: Container) {
var argument: String?
container.register(LoginViewOutput.self) { (resolver: Resolver, version: String) in
let presenter = LoginPresenter()
presenter.key = version
argument = version // save runtime argument
return presenter
}.initCompleted { (resolver, presenter) in
let presenter = presenter as? LoginPresenter
let version = argument! // get runtime argument
presenter?.interactor = r.resolve(LoginInteractorInput.self, argument: version)
presenter?.view = r.resolve(LoginViewInput.self, argument: version)
presenter?.key = version
}
@makleso6 thank you, I'll check
Thanks @makleso6 for your answer馃槂馃憤馃槂馃憤馃槂馃憤
Most helpful comment
@igorkotkovets
try create new variable after:
func assemble(container: Container)like: