> On Aug 2, 2016, at 7:58 AM, Patrick Lind via swift-evolution 
> <[email protected]> wrote:
> 
> http://stackoverflow.com/questions/38619660/is-it-possible-to-pass-generic-protocols-into-a-constructor-for-proper-dependenc

I *think* that the specific feature you're looking for here is usually called 
"enhanced existentials". This would have a different syntax—something like 
`RepositoryProtocol where Object == Zombie`—but would do basically the same 
thing.

The way to work around this in Swift 2 or 3 is to manually write a type-erasing 
wrapper:

        // Effectively a constructor of AnyRepository.
        public func anyRepository<Repository: RepositoryProtocol>(_ repository: 
Repository) -> AnyRepository<Repository.Object> {
                // Don't double-wrap
                if let repo = repository as? AnyRepository<Repository.Object> {
                        return repo
                }
                return ConcreteAnyRepository(repository: repository)
        }
        
        // This is the public face of the wrapper. It's actually abstract. 
Since it doesn't have the 
        // RepositoryProtocol as a parameter, it "erases" the repository's type.
        public class AnyRepository<Object>: RepositoryProtocol {
                private init() {}
                
                public var items: Array<Object> {
                        get { fatalError("abstract") }
                        set { fatalError("abstract") }
                }
                
                public func insert(_ object: Object) {
                        fatalError("abstract")
                }
                
                public func deleteAll() {
                        fatalError("abstract")
                }
        }
        
        // All instances of AnyRepository will actually belong to this concrete 
subclass, which 
        // *does* have the specific RepositoryProtocol as a parameter.
        private class ConcreteAnyRepository<Repository: RepositoryProtocol>: 
AnyRepository<Repository.Object> {
                private let repository: Repository
                
                override var items: Array<Object> {
                        get { return repository.items }
                        set { repository.items = newValue }
                }
                
                override func insert(_ object: Object) {
                        repository.insert(object)
                }
                
                override func deleteAll() {
                        repository.deleteAll()
                }
        }

And then your ZombieServiceProtocol can look like:

        protocol ZombieServiceProtocol {
            func fetchZombies()
        
            var zombieRepository: AnyRepository<Zombie> { get set }
        }

-- 
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to