Swinject register UIViewController best practice
At this point in my project I am using Swinject (DI container).
I want to know how to register a ViewController if I have the following hierarchy:
class RateAnswersBaseVC: UIViewController { }
class RateAnswersDoctorVC: RateAnswersBaseVC { }
class RateAnswersQualityVC: RateAnswersBaseVC { }
How is their right to register and use? I have two options at this point in the project in which I use the first option, but it makes sense that we should use the second :)
// ------- 1 --------
container.register(RateAnswersDoctorVC.self) { r in
let vc: RateAnswersDoctorVC = RateAnswersDoctorVC()
self.configureBasicFields(with: vc, container: container, resolver: r)
return vc
}
container.register(RateAnswersQualityVC.self) { r in
let vc: RateAnswersQualityVC = RateAnswersQualityVC()
self.configureBasicFields(with: vc, container: container, resolver: r)
return vc
}
// ------- 2 --------
container.register(RateAnswersBaseVC.self, name: "doctor") { r in
let vc: RateAnswersDoctorVC = RateAnswersDoctorVC()
self.configureBasicFields(with: vc, container: container, resolver: r)
return vc
}
container.register(RateAnswersBaseVC.self, name: "quality") { r in
let vc: RateAnswersQualityVC = RateAnswersQualityVC()
self.configureBasicFields(with: vc, container: container, resolver: r)
return vc
}
I would be glad if you could explain why you are using this or that method.
thanks for answers
source to share
Umh, with 1 or 2, you are still registering an instance. In this case, I don't see any difference.
These are ViewControllers, so things are a little more complicated, but what will matter is whether to register them RateAnswersBaseVC
as a protocol, RateAnswersBaseVCService
or RateAnswersBaseVCProtocol
so you can create another implementation of the View controller in your test for testing.
source to share
Last time I use MVVM pattern in my projects. So I split the business logic of the application into modules - a complete piece of code that provides some functionality or business logic (for example, logging into an application, playing a video in full screen, etc.). For each module, I create an object Assembly
to set up the dependencies in the module.
class PasswordAssembly: Assembly {
func assemble(container: Container) {
container.register(PasswordViewInterface.self) { (_: Resolver) in
PasswordViewController(nibName: "PasswordViewController", bundle: nil)
}
.initCompleted { resolver, view in
var view = view as PasswordViewInterface
view.viewModel = resolver.resolve(PasswordViewModelInterface.self)
view.router = resolver.resolve(PasswordRouterInterface.self)
}
container.register(PasswordViewModelInterface.self) { (resolver: Resolver) in
return PasswordViewModel(coreModel: resolver.resolve(CoreViewModelInterface.self)!)
}
container.register(PasswordRouterInterface.self) { _ in
return PasswordRouter()
}
.initCompleted { (resolver, router) in
var router = router as PasswordRouterInterface
router.view = resolver.resolve(PasswordViewInterface.self)
router.resolver = container
}
}
}
Also I add to router Resolver
(Container) object to make build hierarchyRouter
protocol PasswordRouterInterface {
var view: PasswordViewInterface! { get set }
var resolver: Resolver! { get set }
func presentFilesListView()
func presentContentView()
}
class PasswordRouter: PasswordRouterInterface {
var view: PasswordViewInterface!
var resolver: Resolver!
func presentFilesListView() {
if let listViewController = resolver.resolve(FilesListViewInterface.self)?.getViewController() {
let navigationController = UINavigationController(rootViewController: listViewController)
view.getViewController().present(navigationController, animated: true) {
}
}
}
func presentContentView() {
}
}
source to share