Swift NSCache Singleton I want to wrap NSCache in a Singleton in order to use dependency injection in my code. This has resulted, rather unfortunately, in passing the type through a function parameter, and I even need two mocks for success and failure since it is a singleton instance.
I think there might be a better way, but any comments appreciated!
ImageCache and protocol
protocol ImageCacheProtocol {
    static var shared: Self { get }
    func getCache() -&gt; NSCache&lt;AnyObject, UIImage&gt;
}

final class ImageCache: ImageCacheProtocol {
    var cache: NSCache&lt;AnyObject, UIImage&gt; = NSCache&lt;AnyObject, UIImage&gt;()

    public static let shared = ImageCache()
    private init() {}
    
    func getCache() -&gt; NSCache&lt;AnyObject, UIImage&gt; {
        return cache
    }
}

MockImageCache &amp; MockImageCacheFailure
final class MockImageCache: ImageCacheProtocol {
    var cache: NSCache&lt;AnyObject, UIImage&gt; = MockNSCache(shouldReturnImage: true)

    public static let shared = MockImageCache()
    private init() {}

    func getCache() -&gt; NSCache&lt;AnyObject, UIImage&gt; {
        return cache
    }
}


final class MockImageCacheFailure: ImageCacheProtocol {
    var cache: NSCache&lt;AnyObject, UIImage&gt; = MockNSCache(shouldReturnImage: false)

    public static let shared = MockImageCacheFailure()
    private init() {}

    func getCache() -&gt; NSCache&lt;AnyObject, UIImage&gt; {
        return cache
    }
}

Instantiating my view model (snippet)
class ViewModel&lt;U: ImageCacheProtocol&gt; {

    private var cache: U.Type
    init&lt;T: NetworkManagerProtocol&gt;(networkManager: T, data: DisplayContent, imageCache: U.Type) {
        self.networkManager = AnyNetworkManager(manager: networkManager)
        
        cache = imageCache
Yes, this isn't the canonical way. My solution is to not use Self and to instead focus on shared.
That is:
protocol ImageCacheProtocol {
    func getCache() -&gt; NSCache&lt;AnyObject, UIImage&gt;
}

final class ImageCache: ImageCacheProtocol {
    var cache: NSCache&lt;AnyObject, UIImage&gt; = NSCache&lt;AnyObject, UIImage&gt;()
    static var shared = ImageCache()
    
    private init() {}
    
    func getCache() -&gt; NSCache&lt;AnyObject, UIImage&gt; {
        return cache
    }
}

Then the mocks can be altered:
final class MockImageCache: ImageCacheProtocol {
    var cache: NSCache&lt;AnyObject, UIImage&gt; = MockNSCache(shouldReturnImage: true)
    public static var shared: ImageCacheProtocol! = MockImageCache()
    func getCache() -&gt; NSCache&lt;AnyObject, UIImage&gt; {
        return cache
    }
}