So here I have this protocol
public protocol UseCase {
associatedtype ResponseType
associatedtype Parameters
func build(params: Parameters) -> Single<ResponseType>
}
public extension UseCase {
func execute(params: Parameters) -> Single<ResponseType> {
return build(params: params)
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: DispatchQoS.background))
.observeOn(MainScheduler.instance)
}
}
And I have a Struct that implement the UseCase
protocol like this
public struct CreateNewAccount: UseCase {
private let repository: AuthRepository
public init(repository: AuthRepository) {
self.repository = repository
}
public func build(params: Params) -> Single<User> {
return repository.register(params: params)
}
public struct Params: RequestParams {
...
}
}
And I want to use this CreateNewAccount
on another class, but I don't want to directly use CreateNewAccount
and I want to pass it as a UseCase
instead, because since It's a protocol It can be easily mocked for testing.
But when I do something like this
class RegisterViewModel: ViewModel {
private let createNewAccount: UseCase // Error on this line
init(createNewAccount: UseCase) { // Error on this line
self.createNewAccount = createNewAccount
}
}
That gave me an error like this
Error:(34, 35) protocol 'UseCase' can only be used as a generic constraint because it has Self or associated type requirements
So, is there's something that I can change from my code to make this kind of case works? Thanks in advance.
You cannot use protocols with associated type as a field.
You have to use them only as an implementation of classes. In most cases, those classes should are generic.
For instance, this code is allowed:
public struct CreateNewAccount<T, K>: UseCase {
public typealias ResponseType = T
public typealias Parameters = K
}
and so,
private let createNewAccount: CreateNewAccount<YouClass1,YouClass2>
or wrap it somehow by another protocol.