我正在尝试使用 Swinject 注入(inject)依赖项,但我不知道我做错了什么。
我有处理注册用户的协议(protocol)。
protocol AuthServiceProtocol {
func registerUser(email: String, password: String, completion: @escaping CompletionHandler) }
并且符合此协议(protocol)的类完成所有逻辑:
class AuthService: AuthServiceProtocol {
func registerUser(email: String, password: String, completion: @escaping CompletionHandler) {
let lowerCaseMail = email.lowercased()
let body: [String: Any] = [
"email": lowerCaseMail,
"password" : password
]
Alamofire.request(URL_REGISTER, method: .post, parameters: body, encoding: JSONEncoding.default, headers: HEADER).responseString { (response) in
if response.result.error == nil {
completion(true)
} else {
completion(false)
debugPrint(response.result.error as Any)
}
}
}
}
所以,在 AppDelegate 中我们注册容器,它看起来像:
let container = Container() { container in
container.register(AuthServiceProtocol.self) { _ in AuthService() }.inObjectScope(.container)
container.register(CreateAccountVC.self) { r in
let controller = CreateAccountVC()
controller.authService = r.resolve(AuthServiceProtocol.self)
return controller
}
}
但是在CreateAccountVC authService 中是空的。有什么想法我该怎么做吗? CreateAccountVC是ViewController的子类,我已经通过属性和构造函数尝试过它,但它始终为零。
最佳答案
检查您的代码:
var container : Container {
let container = Container()
container.register(AuthServiceProtocol.self) { _ in AuthService() }.inObjectScope(.container)
container.register(CreateAccountVC.self) { r in
let controller = CreateAccountVC()
controller.authService = r.resolve(AuthServiceProtocol.self)
print(r.resolve(AuthServiceProtocol.self))
return controller
}
return container
}
您有计算属性,每次调用它时,它都会创建一个新的容器对象。
重构您的代码以拥有单个容器,我相信您会很顺利。
编辑:
这是一个有效的代码片段。 下面是一个小包装类,用于抽象具体的 DI 服务(以防 Swinject 有一天被其他东西替换):
import Swinject
public class ConfigurationProvider {
// Currently using Swinject
private let backingService = Container()
// Singleton
public static let shared = ConfigurationProvider()
// Hidden initializer
private init() {}
// MARK: - Bind / Resolve
public func bind<T>(interface: T.Type, to assembly: T) {
backingService.register(interface) { _ in assembly }
}
public func resolve<T>(interface: T.Type) -> T! {
return backingService.resolve(interface)
}
}
// Extension methods to ignore 'shared.' call, like:
// ConfigurationProvider.bind(interface: IAssembly, to: Assembly())
// ConfigurationProvider.resolve(interface: IAssembly)
public extension ConfigurationProvider {
static func bind<T>(interface: T.Type, to assembly: T) {
ConfigurationProvider.shared.bind(interface: interface, to: assembly)
}
static func resolve<T>(interface: T.Type) -> T! {
return ConfigurationProvider.shared.resolve(interface: interface)
}
}
用法:
class RSAuthLoginModuleAssembly: IAuthLoginModuleAssembly {
}
// Register:
ConfigurationProvider.bind(interface: IAuthLoginModuleAssembly.self, to: ConcreteAuthLoginModuleAssembly())
// Resolve:
guard let assembly = ConfigurationProvider.resolve(interface: IAuthLoginModuleAssembly.self) else {
throw NSError(domain: "Assembly cannot be nil", code: 999, userInfo: nil)
}
关于ios - 如何使用 swinject 正确注入(inject)依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46768990/