如何解决如何在类型上使用 Property Wrapper 抽象单例?
在协议中,我想从函数创建一个实例,所以我使用一个容器来存储这样的静态实例:
protocol MyProtocol {
func networkService() -> NetworkService
}
extension MyProtocol {
func networkService() -> NetworkService {
if Singletons.networkService == nil {
Singletons.networkService = NetworkService(abc: 123)
}
return Singletons.networkService!
}
}
private enum Singletons {
static var networkService: NetworkService?
}
稍后,类型可以符合它并替换默认实现,但也需要单个实例:
struct MyType: MyProtocol {
private static var networkService: NetworkService?
func networkService() -> NetworkService {
if Self.networkService == nil {
Self.networkService = NetworkService(abc: 555)
}
return Self.networkService!
}
}
我希望通过使用 Property Wrapper 封装这个创建单例的仪式,但在类型上。我想做这样的事情:
protocol MyProtocol {
func networkService() -> NetworkService
}
extension MyProtocol {
func networkService() -> NetworkService {
@Singleton
NetworkService(abc: 123)
}
}
////
struct MyType: MyProtocol {
func networkService() -> NetworkService {
@Singleton
NetworkService(abc: 555)
}
}
有没有办法实现这个或类似的东西?
解决方法
这是我的第一次尝试:
struct Single {
private static var instances = [String: Any]()
static func make<T>(_ instance: () -> T) -> T {
let key = String(describing: type(of: T.self))
guard let value = instances[key] as? T else {
let resolved = instance()
instances[key] = resolved
return resolved
}
return value
}
}
protocol NetworkService {}
struct NetworkDefaultService: NetworkService {
let id = UUID().uuidString
init() {
print("Network Default: \(id)")
}
}
struct NetworkMockService: NetworkService {
let id = UUID().uuidString
init() {
print("Network Mock: \(id)")
}
}
protocol LocationService {}
class LocationDefaultService: LocationService {
let id = UUID().uuidString
init() {
print("Location Default: \(id)")
}
}
protocol NonSingleService {}
struct NonSingleDefaultService: NonSingleService {
let id = UUID().uuidString
init() {
print("Non-Single Default: \(id)")
}
}
protocol Context {
func networkService() -> NetworkService
func locationService() -> LocationService
func nonSingleService() -> NonSingleService
}
extension Context {
func networkService() -> NetworkService {
Single.make {
NetworkDefaultService()
}
}
func locationService() -> LocationService {
Single.make {
LocationDefaultService()
}
}
}
struct AppContext: Context {
func networkService() -> NetworkService {
Single.make {
NetworkMockService()
}
}
func nonSingleService() -> NonSingleService {
NonSingleDefaultService()
}
}
let context = AppContext()
context.networkService()
context.networkService()
context.locationService()
context.locationService()
context.nonSingleService()
context.nonSingleService()
打印:
Network Mock: 48CBDE3A-26D2-4767-A6AA-F846F8863A52
Location Default: 4846953B-93F6-4025-A970-DA5B47470652
Non-Single Default: 957979D8-9F3E-428E-BD87-B9F45D56B755
Non-Single Default: 816D2886-D606-4558-A842-295C833AE4C8
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。