我正试图在使用泛型的Swift 3中完成面向协议的编程。这还没有完全支持吗?我会告诉你我想在下面做什么,但不会编译。我在这里错过了什么吗?我的目标是能够使用面向协议的编程来执行依赖注入,以便在单元测试中轻松地模拟这些结构。是否有可能将通用协议传递给Swift 3中正确的依赖注入构造函数?
protocol ZombieServiceProtocol {
func fetchZombies()
var zombieRepository: RepositoryProtocol<Zombie> { get set }
}
struct ZombieService: ZombieServiceProtocol {
var zombieRepository: RepositoryProtocol<Zombie>
init(zombieRepository: RepositoryProtocol<Zombie>) {
self.zombieRepository = zombieRepository
}
func fetchZombies() {
self.zombieRepository.deleteAll()
self.createFakeZombies()
}
private func createFakeZombies() {
for index in 1...100 {
let zombie = Zombie(id: index, name: "Zombie \(index)")
self.zombieRepository.insert(zombie)
}
}
}
僵尸类看起来是这样的:
public struct Zombie: Persistable {
var id: Int
let name: String?
init(id: Int, name: String?) {
self.id = id
self.name =name
}
}
它的持久化协议看起来是这样的:
protocol Persistable {
var id: Int { get set }
}
而且我的仓库代码看起来是这样的:
protocol RepositoryProtocol: class {
associatedtype Object: Persistable
//...
func insert(_ object: Object) -> Void
func deleteAll(_ predicate: (Object) throws -> Bool) -> Void
}
class Repository<Object: Persistable>: RepositoryProtocol {
var items = Array<Object>()
//...
func insert(_ object: Object) {
self.items.append(object)
}
func deleteAll() {
self.items.removeAll()
}
}
我得到了followi NG错误在我ZombieServiceProtocol:
- 不能专注非泛型类型 'RepositoryProtocol'
我得到了我的ZombieService以下错误:
- 不能专注非泛型类型“RepositoryProtocol '
- 成员'insert'不能用于协议类型的值 'RepositoryProtocol';使用一个通用的约束,而不是
,并强调正是我试图完成,这里是一个简单的测试是什么样子的,我创建一个模拟库,并尝试使用,而不是在一个真正的我的ZombieService:
@testable import ZombieInjection
class ZombieServiceTests: XCTestCase {
private var zombieRepository: RepositoryProtocol<Zombie>!
private var zombieService: ZombieServiceProtocol
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
self.zombieRepository = RepositoryMock<Zombie>()
self.zombieService = ZombieService(zombieRepository: self.zombieRepository)
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// Arrange
// Act
self.zombieService.fetchZombies()
// Assert
XCTAssert(self.zombieRepository.count() > 0)
}
}
此代码也不会与上述相同的错误进行编译。
我一直在寻找associatedTypes和typeAlias标签以及Generics Manifesto。在看“宣言”时,我认为这属于“通用协议”部分,该部分目前标记为“不太可能”(这是令人沮丧的)。如果我无法完成上述的尝试,那么下一个最佳解决方案是什么?
看起来像是一个响亮的否?去尝试和重构,看看我还能做些什么... – PkL728