【发布时间】:2018-04-20 09:19:45
【问题描述】:
我正在研究依赖注入,目前正在更新我的项目以使用它。但是,我遇到了关联类型和协议一致性的问题。
我创建了一个快速演示项目,并创建了一些协议和扩展,以便符合我的协议 ViewModelBased 的视图控制器必须实现关联类型。理想情况下,我希望此关联类型符合 viewModel。这是我目前所拥有的
protocol ViewModel {
associatedtype Services
init (withServices services: Services)
}
protocol ViewModelBased: class {
associatedtype ViewModelType
var viewModel: ViewModelType { get set }
}
extension ViewModelBased where Self: UIViewController{
static func instantiateController(with viewModel : ViewModelType) -> Self {
// I have created UIStoryboard extension to allow for easy opening of view controllers
// in storyboard
let viewController : Self = UIStoryboard.mainStoryboard.instantiateViewController()
viewController.viewModel = viewModel
return viewController
}
}
所以我的应用程序中的所有视图模型都符合视图模型,这迫使它们实现服务类型。例如,我的 LoginModel 如下所示
struct LoginModel : ViewModel{
// service type
typealias Services = LoginService
// init service
var services : LoginService
init(withServices services: LoginService) {
self.services = services
}
/// calls login service - attempts login api
func attemptLogin() {
services.login()
}
}
所以这里是一个实现这个的 viewController 的例子
class SecondController: UIViewController, ViewModelBased {
var viewModel: LoginModel!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func loginTest() {
viewModel.services.onLoginSuccess = { isVerified in
print(isVerified)
}
viewModel.services.onLoginFailure = { errorCode in
print(errorCode)
}
viewModel.attemptLogin()
}
}
所以把它们放在一起,这允许应用程序初始化一个 viewController 并像这样传递一个 viewModel
let loginModel = LoginModel(withServices: LoginService())
let controller = SecondController.instantiateController(with: loginModel)
self.navigationController?.pushViewController(controller, animated: true)
这一切都很好,但我遇到的问题是,关联的类型目前可以是任何类型。理想情况下,我希望这个 associatedType 符合 ViewModel 协议。但是当我尝试这个时
protocol ViewModelBased: class {
associatedtype ViewModelType : ViewModel
var viewModel: ViewModelType { get set }
}
我的 SecondController 现在抛出一个错误,现在强制我初始化 LoginModel
var viewModel : LoginModel = LoginModel(withServices: LoginService())
但这不再使用依赖注入,因为 viewController 现在负责创建 viewModel 实例并知道 viewModel 类的行为。
有什么办法可以解决这个问题吗?如果有人能给我一些关于我做错了什么的信息,我将不胜感激。
【问题讨论】:
标签: swift swift-protocols