4

At this point in my project I use Swinject (DI Container).

I want to know how to register the ViewController, if I have the following hierarchy:

class RateAnswersBaseVC: UIViewController { }
class RateAnswersDoctorVC: RateAnswersBaseVC { }
class RateAnswersQualityVC: RateAnswersBaseVC { }

How will their right to register and use? I have two options at this point in the project I use the first option, but there is a 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 explain why you use one or the other method.

Thanks for the replies

2 Answers2

1

Last time I use MVVM pattern in my projects. So I split business logic of the app to modules - a completed part of code which provides some feature or business logic (like Login in the app, playing video in fullscreen etc). For each module I create an Assembly object to configure 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 inject in router Resolver (Container) object to make Router build hierarchy

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() {

    }
}
Ihar Katkavets
  • 1,510
  • 14
  • 25
0

Umh, either with 1 or 2, you are still registering a instance. I don't really see any difference in this case.

These are ViewControllers so things are a bit more complicated, but what would make a difference would be to register them not as RateAnswersBaseVC, but as a protocol RateAnswersBaseVCService or RateAnswersBaseVCProtocol so that you could then create a different implementation of the View Controller in the mocks for testing.

Marco Pappalardo
  • 935
  • 6
  • 23