hmlongco / Resolver

Swift Ultralight Dependency Injection / Service Locator framework
MIT License
2.14k stars 188 forks source link

Workarounds for using protocol with associated types? #96

Closed jessegrosjean closed 3 years ago

jessegrosjean commented 3 years ago

I'm trying to use a service that has an associated type:

protocol TestServiceType {
    associatedtype Value
}

struct TestService: TestServiceType {
    typealias Value = Int
}

struct TestConsumer {
    @Injected var testService: TestServiceType<Int>
}

extension Resolver {
    public static func registerTestService() {
        register{ TestService() }
            .implements(TestServiceType<Int>.self)
    }
}

I think I understand why this is a problem in the generic case... but is there some way that I can register a concrete "instance" of this protocol with Resolver? For example I would like to register TestServiceType <Int>, but I can't figure out how.

I'm not sure if I am just getting swift syntax wrong, or if it's just not possible. And if it isn't possible I'm wondering if there's some workaround that I can use?

Thanks, Jesse

hmlongco commented 3 years ago

Yeah, you're deep into the generics "has associated type requirements" issue in Swift. You can't specialize the type as illustrated here. Hmmm.

The only thing I can think of is to type erase your protocol to some sort of AnyTestServiceType and inject that.

jessegrosjean commented 3 years ago

Thanks, that sounds reasonable to me.