I'm trying to write a static generic method which takes a protocol as an argument and register class instance in Swinject container as a protocol resolve. It's important that I could not register a module as a protocol it does not conforms to.
I wrote something like this:
/// RegisterableModule guarantee that conformer has `create()` method returning self
public extension RegisterableModule {
static func registerModule<P>(asProtocol proto: P.Type,
in container: Container) {
container.register(proto, name: nil) { (resolver) -> P in
return self.create()
}
}
}
It does not compile because obviously Self may be not conforming to P
I also tried to specify generic constraint using where
:
where Self: P
does compile error "Type 'Self' constrained to non-protocol, non-class type 'P'" where self: P
does multiple compiles error. where Self: P.Type
does compile error "Type 'Self' constrained to non-protocol, non-class type 'P.Type'" where self: P.Type
does multiple compile errors. I also wonder if I can specify a constraint that P can be protocol only.
Unfortunatelly, there is no way (yet) in Swift to define requirement of conformance to generic parameters, or require parameter to be a protocol.
This is the reason why Swinject's type-forwarding API is not type safe . There is a "trick" that sort-of enables one to express a conformance requirement, however I'm not sure if it would be practical for your use-case:
extension RegisterableModule {
static func registerModule<P>(
asProtocol proto: P.Type,
in container: Container,
typeCheck: (Self) -> P
) {
container.register(proto) { _ in self.create() as! P }
}
}
MyModule.registerModule(
asProtocol: MyProtocol.self,
in: container,
typeCheck: { $0 }
)
Can you try it, I just added P:SomeProtocol
public extension RegisterableModule {
static func registerModule<P:SomeProtocol>(asProtocol proto: P.Type,
in container: Container) {
container.register(proto, name: nil) { (resolver) -> P in
return self.create()
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.