Reputation: 11
I wanted to develop an application which uses repository patterns using core data and realm. I want to resolve protocol according to my needs. Purpose is to inject a generic core data repository / realm repository protocol in the assembly.
Problem occurs on this line saying 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)
}
I am unable to inject sleep repository protocol because of using generic (associated type) properties. How can I solve this problem?
Additionally,thank you very much for your response. It really helped me a lot. I have one more issue with this.
var repository: SleepRepositoryProtocol
var items: [SleepEntity]?
private let assembler: Assembler
init(assembler: Assembler) {
self.assembler = assembler
repository = assembler.resolver.resolve(SleepRepositoryProtocol.self)!
}
This gives me error "Protocol 'SleepRepositoryProtocol' can only be used as a generic constraint because it has Self or associated type requirements" and I don't know how to resolve my SleepRepositoryProtocol.
Upvotes: 1
Views: 555
Reputation: 2661
This error is a classic:
container.register(SleepRepositoryProtocol.self) { r in
is forbidden because SleepRepositoryProtocol
is a Protocol with Associated Type.
what you would need is for the assemble(container:)
method to be generic and declared this way for example:
func assemble<Repository: SleepRepositoryProtocol>(container: Container, ofType type:Repository) {
but since it's part of Swinject's Assembly Protocol it is not an option and you need to find another place to put the Generic Type Constraint.
In your case it can be the enclosing type eg.:
class MyClass<Repository: SleepRepositoryProtocol>: Assembly {
func assemble(container: Container) {
container.register(Repository.self) { r in
CoreDataSleepRepository(persistentContainer:r.resolve(NSPersistentContainer.self)!)
}
.inObjectScope(.container)
}
}
you cannot just write :
var repository: SleepRepositoryProtocol
Once you add associatedtype
in you protocol you can never use it like a normal type, only as a Generic Type Constraint
So if I update MyClass
with your other properties:
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)
}
}
Upvotes: 1