1

我想开发一个使用核心数据和领域的存储库模式的应用程序。我想根据我的需要解决协议。目的是在程序集中注入一个通用的核心数据存储库/领域存储库协议。

这条线出现问题说Protocol 'SleepRepositoryProtocol' can only be used as a generic constraint because it has Self or associated type requirements

func assemble(container: Container) {
    container.register(SleepRepositoryProtocol.self) { r in
        CoreDataSleepRepository(persistentContainer:r.resolve(NSPersistentContainer.self)!)
        }.inObjectScope(.container)
}

由于使用通用(关联类型)属性,我无法注入睡眠存储库协议。我怎么解决这个问题?

另外,非常感谢您的回复。它真的帮了我很多。我对此还有一个问题。

var 存储库:SleepRepositoryProtocol

var items: [SleepEntity]?

private let assembler: Assembler

init(assembler: Assembler) {
    self.assembler = assembler
    
    repository = assembler.resolver.resolve(SleepRepositoryProtocol.self)!
}

这给了我错误“协议 'SleepRepositoryProtocol' 只能用作通用约束,因为它具有 Self 或关联的类型要求”,我不知道如何解决我的 SleepRepositoryProtocol。

4

1 回答 1

0

这个错误很经典:

    container.register(SleepRepositoryProtocol.self) { r in

被禁止,因为SleepRepositoryProtocol具有关联类型的协议

您需要的是使该assemble(container:)方法具有通用性并以这种方式声明,例如:

func assemble<Repository: SleepRepositoryProtocol>(container: Container, ofType type:Repository) {

但由于它是Swinject 的 Assembly Protocol的一部分,因此它不是一个选项,您需要找到另一个放置Generic Type Constraint的地方。

在您的情况下,它可以是封闭类型,例如:

class MyClass<Repository: SleepRepositoryProtocol>: Assembly {
    func assemble(container: Container) {
        container.register(Repository.self) { r in
          CoreDataSleepRepository(persistentContainer:r.resolve(NSPersistentContainer.self)!)
        }
        .inObjectScope(.container)
    }
}

编辑

你不能只写:

var repository: SleepRepositoryProtocol

一旦你添加associatedtype了你的协议,你就永远不能像普通类型一样只作为通用类型约束

因此,如果我MyClass使用您的其他属性进行更新:

class MyClass<Repository: SleepRepositoryProtocol>: Assembly {
    var repository: Repository

    var items: [SleepEntity]?

    private let assembler: Assembler

    init(assembler: Assembler) {
        self.assembler = assembler
        
        repository = assembler.resolver.resolve(Repository.self)!
    }

    func assemble(container: Container) {
        container.register(Repository.self) { r in
          CoreDataSleepRepository(persistentContainer:r.resolve(NSPersistentContainer.self)!)
        }
        .inObjectScope(.container)
    }
}
于 2021-05-01T14:59:09.307 回答