У меня есть протокол с ассоциированным типом
protocol IBaseDao {
associatedtype Entity
func insert(e: Entity, completion: @escaping (Result<Entity, Error>) -> Void)
func insertReplacing(e: Entity, completion: @escaping (Result<Entity, Error>) -> Void)
func delete(e: Entity, completion: @escaping (Result<Int, Error>) -> Void)
func update(e: Entity, completion: @escaping (Result<Entity, Error>) -> Void)
func load(id: String, completion: @escaping (Result<Entity, Error>) -> Void)
func loadAll(completion: @escaping (Result<[Entity], Error>) -> Void)
}
Затем я хочу добавить конкретные протоколы для конкретного типа сущности, например, так:
protocol IMoviesDao : IDao where Entity == Movie {
func load(query: String, completion: @escaping (Result<[Movie], Error>) -> Void)
}
Затем у меня есть реализация BaseDao, как показано ниже:
class UserDefaultsDao<T> : IDao {
typealias Entity = T
}
Тогда у меня есть реализация конкретного класса Dao:
class MoviesUserDefaultsDao : UserDefaultsDao<Movie>, IMoviesDao {
}
Наконец, я хотел бы использовать:
final class MoviesRepository {
private let moviesService : IMoviesService
private let moviesDao : IMoviesDao
}
Но здесь я получаю сообщение об ошибке:
Протокол 'IMoviesDao' можно использовать только в качестве общего ограничения, поскольку он имеет требования к Self или связанные с типами
Можно ли как-то обойти эту проблему?Я считаю, что повторное указание тех же методов в IMoviesDao, что и в IBaseDao, и удаление наследования (расширения) протокола сделают эту работу, но затем мне нужно переписать эти методы для каждого протокола Dao
ОБНОВЛЕНИЕ:
Так что теперь мне нужно продублировать этот метод
protocol IMoviesDao {
func load(query: String, completion: @escaping (Result<[Movie], Error>) -> Void)
func insert(e: Movie, completion: @escaping (Result<Movie, Error>) -> Void)
func insertReplacing(e: Movie, completion: @escaping (Result<Movie, Error>) -> Void)
func delete(e: Movie, completion: @escaping (Result<Int, Error>) -> Void)
func update(e: Movie, completion: @escaping (Result<Movie, Error>) -> Void)
func load(id: String, completion: @escaping (Result<Movie, Error>) -> Void)
func loadAll(completion: @escaping (Result<[Movie], Error>) -> Void)
}