My data access layer consists of a generic Repository protocol
protocol Repository {
associatedtype T
func getAll() -> Promise<[T]>
}
and its concrete implementation:
class FirebaseRepository<T: Model>: Repository {
func getAll() -> Promise<[T]> {
fatalError()
}
}
Basically, Repository can be RestRepository, FirebaseRepository, PlistRepositry etc. Repository is used by the business logic:
/// My business logic
class ModelService<T: Repository> {
private let repository: T
public init(repository: T) {
self.repository = repository
}
}
The problem comes when I'm trying to apply a factory pattern to a repository. Here's what I came in first:
/// Returns a concrete Repository implementation
class RepositoryFactory {
func makeRepository<T: Model>(type: T.Type) -> Repository {
return FirebaseRepository<T>()
}
}
and this definitely gets a compiler error:
Protocol 'Repository' can only be used as a generic constraint because it has Self or associated type requirements
The only viable option I came to is this:
func makeRepository<T: Model>(type: T.Type, U: Repository) -> U {
return FirebaseRepository<T>() as! U
}
but as you understand, the force optional unwrapping is not acceptable in the production code.
How to make protocols with associated types work with factory design pattern?
Aucun commentaire:
Enregistrer un commentaire